React Hooks documentation建议使用ref来访问state / props的先前值,甚至将其抽象到usePrevious
自定义钩子中。
文档示例(使用按钮修改):
function Counter() {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
return <div>
<h1>Now: {count}, before: {prevCount}</h1>
<button onClick={() => setCount(c => c + 1)}>Add</button>
</div>
}
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
我在玩《 Counter》示例,并注意到如果您使用另一个不相关的钩子进行更新,它会中断。
export default function Counter() {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
const [color, setColor] = useState("black");
useEffect(() => {
// This breaks the prev count counter: when displayed on screen, previous = count
setColor(count % 2 ? "red" : "blue");
}, [count]);
return (
<div>
<h1>Now: {count}, before: {prevCount}</h1>
<button style={{ color }} onClick={() => setCount(c => c + 1)}>
Add
</button>
</div>
);
}
...
似乎是由状态更新触发的重新渲染导致了此问题,因为在将示例设置为恒定值时,该示例按预期工作:
...
useEffect(() => {
// This works: When displayed, previous = count - 1
setColor("black");
}, [count]);
...
所以我的问题是:
答案 0 :(得分:1)
先前的值是上次渲染时的值计数,而不是先前的值(如果有意义)。
由于颜色变化时渲染之间的计数没有改变,因此计数等于该渲染上的previousCount。
请改为使用另一个useState来跟踪lastCount并在调用setCount时对其进行更新。
const [lastCount, setLastCount] = useState(0);
<button style={{ color }} onClick={() => {
let currentCount;
setCount(c => {currentCount = c; return c + 1;});
setLastCount(currentCount);
}
}>
Add
</button>
在您的示例中,上一个值的有用之处在于您是否在询问“此渲染是否是由于计数更新引起的?”。如果count等于previousCount,则答案为否。