Children 不通过 Ref 更新道具更改
Children do not update on props change via Ref
我有以下 React 组件:
import { useRef, useEffect, useState } from "react";
function Child({ containerWidth }) {
console.log("CHILD", containerWidth);
return <div>My parent's width is {containerWidth}px</div>;
}
export default function App() {
const containerRef = useRef(null);
const [containerWidth, setContainerWidth] = useState(null);
const [width, setWidth] = useState(400);
console.log("PARENT", containerWidth);
useEffect(() => {
if (containerRef.current) {
setContainerWidth(containerRef.current.clientWidth);
}
}, [containerRef]);
const handleWidth = () => setWidth(1000);
console.log("width", width);
return (
<div ref={containerRef} style={{ width: width }}>
<Child containerWidth={containerWidth} />
<button onClick={handleWidth}>change my width</button>
</div>
);
}
我需要 children 始终知道并在宽度发生变化时重新渲染。即使我们单击按钮更改宽度,此 ref 的值也保持不变。
我试过使用 useCallback 调用函数但没有成功,因为 ref 永远不会改变。
const getChild = useCallback(
() => <Child containerWidth={containerWidth} />,
[containerWidth]
);
(.....)
return (
<div ref={containerRef} style={{ width: width }}>
{getChild()}
<button onClick={handleWidth}>change my width</button>
</div>
);
它确实有效,但只有一次,因为您正在检查 ref 是否存在。一旦它存在,它将不再触发 useEffect
逻辑。您可以使用 useEffect 中的事件侦听器来管理它。我刚刚为您创建了一个示例演示。这是工作代码和框 https://codesandbox.io/embed/wild-flower-ytv2b3?fontsize=14&hidenavigation=1&theme=dark
import { useRef, useEffect, useState } from "react";
function Child({ containerWidth }) {
console.log("CHILD", containerWidth);
return <div>My parent's width is {containerWidth}px</div>;
}
export default function App() {
const containerRef = useRef(null);
const [containerWidth, setContainerWidth] = useState(window.innerWidth);
const [width, setWidth] = useState(400);
console.log("PARENT", containerWidth);
const handleResize = () => {
setContainerWidth(window.innerWidth);
};
useEffect(() => {
window.addEventListener("resize", handleResize, false);
}, []);
const handleWidth = () => setWidth(containerWidth);
console.log("width", width);
return (
<div ref={containerRef} style={{ width: width }}>
<Child containerWidth={width} />
<button onClick={handleWidth}>change my width</button>
</div>
);
}
我有以下 React 组件:
import { useRef, useEffect, useState } from "react";
function Child({ containerWidth }) {
console.log("CHILD", containerWidth);
return <div>My parent's width is {containerWidth}px</div>;
}
export default function App() {
const containerRef = useRef(null);
const [containerWidth, setContainerWidth] = useState(null);
const [width, setWidth] = useState(400);
console.log("PARENT", containerWidth);
useEffect(() => {
if (containerRef.current) {
setContainerWidth(containerRef.current.clientWidth);
}
}, [containerRef]);
const handleWidth = () => setWidth(1000);
console.log("width", width);
return (
<div ref={containerRef} style={{ width: width }}>
<Child containerWidth={containerWidth} />
<button onClick={handleWidth}>change my width</button>
</div>
);
}
我需要 children 始终知道并在宽度发生变化时重新渲染。即使我们单击按钮更改宽度,此 ref 的值也保持不变。
我试过使用 useCallback 调用函数但没有成功,因为 ref 永远不会改变。
const getChild = useCallback(
() => <Child containerWidth={containerWidth} />,
[containerWidth]
);
(.....)
return (
<div ref={containerRef} style={{ width: width }}>
{getChild()}
<button onClick={handleWidth}>change my width</button>
</div>
);
它确实有效,但只有一次,因为您正在检查 ref 是否存在。一旦它存在,它将不再触发 useEffect
逻辑。您可以使用 useEffect 中的事件侦听器来管理它。我刚刚为您创建了一个示例演示。这是工作代码和框 https://codesandbox.io/embed/wild-flower-ytv2b3?fontsize=14&hidenavigation=1&theme=dark
import { useRef, useEffect, useState } from "react";
function Child({ containerWidth }) {
console.log("CHILD", containerWidth);
return <div>My parent's width is {containerWidth}px</div>;
}
export default function App() {
const containerRef = useRef(null);
const [containerWidth, setContainerWidth] = useState(window.innerWidth);
const [width, setWidth] = useState(400);
console.log("PARENT", containerWidth);
const handleResize = () => {
setContainerWidth(window.innerWidth);
};
useEffect(() => {
window.addEventListener("resize", handleResize, false);
}, []);
const handleWidth = () => setWidth(containerWidth);
console.log("width", width);
return (
<div ref={containerRef} style={{ width: width }}>
<Child containerWidth={width} />
<button onClick={handleWidth}>change my width</button>
</div>
);
}