我有一个问题useRef:如果我添加ref.current到 的依赖项列表中useEffect,并且当我更改了 的值时ref.current,useEffect将不会触发内部的回调。
例如:
export default function App() {
const myRef = useRef(1);
useEffect(() => {
console.log("myRef current changed"); // this only gets triggered when the component mounts
}, [myRef.current]);
return (
<div className="App">
<button
onClick={() => {
myRef.current = myRef.current + 1;
console.log("myRef.current", myRef.current);
}}
>
change ref
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
不应该是当useRef.current变化时,里面的东西useEffect就会运行吗?
另外,我知道我可以用useState在这里。这不是我要问的。而且我也知道ref在重新渲染期间保持参照不变,所以它不会改变。但我不是在做类似的事情
const myRef = useRef(1);
useEffect(() => {
//...
}, [myRef]);
Run Code Online (Sandbox Code Playgroud)
我将current值放在 dep 列表中,因此应该会发生变化。
Dim*_*nis 30
我知道我有点晚了,但既然你似乎没有接受任何其他答案,我想我也应该尝试一下,也许这就是对你有帮助的。
难道不应该是当 useRef.current 更改时,useEffect 中的内容就会运行吗?
简短的回答,不。
在 React 中导致重新渲染的唯一原因如下:
useState或useReducer钩子)让我们看看您共享的代码示例中发生了什么:
export default function App() {
const myRef = useRef(1);
useEffect(() => {
console.log("myRef current changed"); // this only gets triggered when the component mounts
}, [myRef.current]);
return (
<div className="App">
<button
onClick={() => {
myRef.current = myRef.current + 1;
console.log("myRef.current", myRef.current);
}}
>
change ref
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
myRef被设置为{current: 1}就是这样。以上3个条件都不满足,所以不再重新渲染。
但是当您单击按钮时会发生什么?你运行一个效果。此效果会更改currentref 对象的值,但不会触发会导致重新渲染的更改(1. 2. 或 3. 中的任何一个)。您可以将裁判视为“效果”的一部分。它们不遵守 React 组件的生命周期,也不影响它。
如果组件现在要重新渲染(例如,由于其父级重新渲染),则会发生以下情况:
myRef被设置为{current: 1}const myRef = useRef(1);没有进一步的效果。console.log(myRef.current)内部效果回调,您现在会看到打印的值为 2(或者无论您在初始渲染和此渲染之间按下按钮多少次)总而言之,由于 ref 更改(ref 是一个值,甚至是对 DOM 元素的引用)而触发重新渲染的唯一方法是使用 ref 回调(如本答案中所建议的那样)并在内部该回调将 ref 值存储到 提供的状态useState。
Gal*_*lit 12
使用useCallBack代替,这是 React 文档的解释:
\n\n\n在此示例中,我们没有选择 useRef,因为对象引用不会通知我们当前引用值的更改。使用回调引用可以确保即使子组件稍后显示测量的节点(例如响应单击),我们仍然会在父组件中收到有关它的通知,并且可以更新测量值。
\n请注意,我们将 [] 作为依赖项数组传递给 useCallback。这确保了我们的 ref 回调在重新渲染之间不会发生变化,因此 React 不会不必要地调用它。
\n
function MeasureExample() {\n const [height, setHeight] = useState(0);\n\n const measuredRef = useCallback(node => {\n if (node !== null) {\n setHeight(node.getBoundingClientRect().height);\n }\n }, []);\n\n return (\n <>\n <h1 ref={measuredRef}>Hello, world</h1>\n <h2>The above header is {Math.round(height)}px tall</h2>\n </>\n );\n}\nRun Code Online (Sandbox Code Playgroud)\n
https://reactjs.org/docs/hooks-reference.html#useref
请记住, useRef 不会在其内容更改时通知您。改变 .current 属性不会导致重新渲染。如果您想在 React 将 ref 附加或分离到 DOM 节点时运行一些代码,您可能需要改用回调 ref。
| 归档时间: |
|
| 查看次数: |
2737 次 |
| 最近记录: |