【发布时间】:2020-04-16 10:50:31
【问题描述】:
我正在尝试使用挂钩来存储状态。这个钩子暴露了对值的引用和一个简单的 mutator 函数。我想有一个不同的更新钩子,它使用所说的突变器。虽然在更新程序中值是正确的,但如果我还有另一个钩子,则该值始终是初始值。这是一个重现问题的示例。
import React, { useEffect, useRef } from "react";
function useCounter() {
const counter = useRef<number>(0);
const increment = () => {
counter.current++;
};
return [counter, increment] as const;
}
function useUpdate() {
const [counter, increment] = useCounter();
console.log("rendering update");
return () => {
increment();
console.log(counter.current);
};
}
function useLoop() {
const update = useUpdate();
const [counter] = useCounter();
console.log("rendering loop");
return () => {
update();
console.log(counter.current);
};
}
export default function App() {
const loop = useLoop();
useEffect(() => {
const id = window.setInterval(loop, 1000);
return () => {
window.clearInterval(id);
};
}, [loop]);
return <div />;
}
在 useUpdate 内部,计数器的值是正确的,但在 useLoop 内部,它始终为 0。我使用 ref 是因为当计数器更改时不需要重新运行挂钩,而且它是一个对象,从循环返回的函数应该通过引用来获取它,并且始终具有最新的值,但事实并非如此。 我的目标是使用类似的模式来编写一个结合 p5js 的模拟。这个问题与 p5 完全无关,所以我只是嘲笑了它的更新功能。 我尝试使用 useState、useCallback 但没有任何效果。
我是钩子新手,这种模式可能完全错误。我欢迎有关使用钩子进行高级分解的提示。
谢谢!
编辑:
问题在于 useCounter 运行了两次并创建了两个不同的、不相关的实例。这是我提出的状态分解解决方案:
import React, { useEffect, useRef } from "react";
function useCounter() {
const counter = useRef<number>(0);
const increment = () => {
counter.current++;
};
return { counter, increment };
}
function useUpdate({ counter, increment }) {
console.log("rendering update");
return () => {
increment();
console.log(counter.current);
};
}
function useLoop(state) {
const update = useUpdate(state);
console.log("rendering loop");
return () => {
update();
console.log(state.counter.current);
};
}
export default function App() {
const state = useCounter();
const loop = useLoop(state);
useEffect(() => {
const id = window.setInterval(loop, 1000);
return () => {
window.clearInterval(id);
};
}, [loop]);
return <div />;
}
【问题讨论】:
标签: reactjs react-hooks