问题描述
我需要制作一个带按钮的样式组件 div,按钮生成 div 的大小。然后嵌套在 div 组件内部的组件显示大小。它必须使用 forwardRef,并且两个组件都必须具有功能性。
基本组件代码:
const StyledComp = () => {
const [size,setSize] = useState({ width: 100,height: 100 });
const [maxMin,setMaxMin] = useState({ max: 500,min: 100 });
const [count,setCount] = useState(0);
let ref = useRef(<Shape />);
const handleResize = () => {
const max = maxMin.max;
const min = maxMin.min;
let width = Math.floor(Math.random() * (max - min)) + min;
let height = Math.floor(Math.random() * (max - min)) + min;
setSize({ width,height });
setCount(count+1);
};
return (
<div className="styled-component">
<Shape height={size.height} width={size.width} ref={ref}>
<ShapeResult count={count} {...{ ref }} />
</Shape>
<p>Width: {size.width}</p>
<p>Height: {size.height}</p>
<button onClick={handleResize}>Generate</button>
</div>
);
};
该组件是一个简单的样式化组件 div,其宽度和高度来自 props。 得到 ref 就好了,我可以在控制台中打印它,它确实显示了元素的当前大小。但是当我尝试通过 innerRef.current.offsetWidth 获取宽度/高度值时,它会获得上一代结果。代码如下:
const ShapeResult = ({ count },ref) => {
let innerRef = React.useRef(ref);
const [countState,setCountState] = useState(0);
const [width,setWidth] = useState(100);
const [height,setHeight] = useState(100);
useEffect(() => {
innerRef = ref;
console.log(innerRef.current);
setWidth(innerRef.current.offsetWidth);
setHeight(innerRef.current.offsetHeight);
setCountState(count);
},[count,ref]);
return (
<div className="shape-result">
<p>Click count: {countState}</p>
<p>Width: {width}px</p>
<p>Height: {height}px</p>
</div>
);
};
const ForwardedResult = React.forwardRef(ShapeResult);
export default ForwardedResult;
我将不胜感激,我一直在寻找答案太久了,这真的不应该是那么艰巨的任务...
解决方法
你的方法似乎不正确。
如下图,在StyledComp
组件中,通过shapeResultForwardRef.current
访问DOM。
const StyledComp = () => {
const [size,setSize] = useState({ width: 100,height: 100 });
const [maxMin,setMaxMin] = useState({ max: 500,min: 100 });
const [count,setCount] = useState(0);
let ref = useRef(<Shape />);
const shapeResultForwardRef = useRef(null); // add
const handleResize = () => {
const max = maxMin.max;
const min = maxMin.min;
let width = Math.floor(Math.random() * (max - min)) + min;
let height = Math.floor(Math.random() * (max - min)) + min;
setSize({ width,height });
setCount(count+1);
};
return (
<div className="styled-component">
<Shape height={size.height} width={size.width} ref={ref}>
<ShapeResult count={count} ref={shapeResultForwardRef} />
</Shape>
<p>Width: {size.width}</p>
<p>Height: {size.height}</p>
<button onClick={handleResize}>Generate</button>
</div>
);
};
另一个:
const ShapeResult = ({ count },ref) => {
return (
<div className="shape-result" ref={ref}>
...
</div>
);
};
const ForwardedResult = React.forwardRef(ShapeResult);
export default ForwardedResult;
,
显然,主要问题出在 useEffect 中。应该是:
setWidth(innerRef.current.getAttribute("width"));
setHeight(innerRef.current.getAttribute("height"));
现在终于更新了