4 回答

TA贡献1900条经验 获得超5个赞
我相信如果没有一些解决方法,这几乎是不可能实现的。要调用setState或不调用,我们必须访问当前状态值。如果我们传入state依赖数组,这是可能的。但随后,该间隔将每秒重新创建。
也可以使用 refs 来实现,但是目前还没有正确的方法来监听ref 的更改。
更新:看起来它可以很好地用作useRef以前的数据持有者。感谢安豪2。
const { useEffect, useState, useRef } = React;
const useRandomIs5x = () => {
const [state, setState] = useState(true);
const ref = useRef(null);
useEffect(() => {
const t0 = setInterval(() => {
const value = Math.floor(Math.random() * 5) % 5 === 0;
if (value === ref.current) return;
ref.current = value;
setState(value);
}, 1000);
return () => clearInterval(t0);
}, []);
return state;
}
const Root = () => {
const bool = useRandomIs5x();
console.log('re-render!', bool);
return <div>test</div>
}
ReactDOM.render(<Root />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

TA贡献1772条经验 获得超8个赞
您可能需要采取一些不同的方法。你不需要随机值,你想要它是否能被 5 整除。所以这就是状态并从钩子返回的内容。随机值只能作为参考。所以尝试这样的事情(代码未经测试,但应该给你一个总体思路):
const useRandomIs5x = () => {
const [divisibleBy5, setDivisibleBy5] = useState(true);
const randomValue = useRef(0);
useEffect(() => {
const t0 = setInterval(() => {
// Set the new random value into a ref so as to not cause re-render
randomValue.current = getRandomValue();
const randIsDivisibleBy5 = randomValue.current % 5 === 0;
// Only if it changes do we update the boolean state and trigger re-render
if (randIsDivisibleBy5 !== divisibleBy5) {
setDivisibleBy5(randIsDivisibleBy5);
}
}, 1000);
return () => clearInterval(to);
}, []);
// Return the boolean state value instead
return divisibleBy5;
}

TA贡献1982条经验 获得超2个赞
我们最好更改状态来存储 is5x 而不是值。一种可能的解决方案是使用 useRef 来检查我们是否应该每秒更新该值。然后,同步 useRef 和状态值。
const useRandomIs5x = () => {
const [state, setState] = useState(false);
const prevIs5x = useRef(false);
useEffect(() => {
const t0 = setInterval(() => {
const is5x = getRandomValue() % 5 === 0;
const isDiff = is5x !== prevIs5x.current;
prevIs5x.current = is5x;
if (isDiff) {
setState((prevState) => !prevState);
}
}, 1000);
return () => clearInterval(t0);
}, []);
return state;
};
添加回答
举报