useState()在useEffect()钩子中没有更新



我在useEffect()中更新useState()时遇到问题。我想我可能会进入一个无限循环,不管我传入的布尔值是多少,useState都不会更新。它总是显示false。

export const useAlert = () => {
const action = useSelector(state => state.edit.action);
const dispatch = useDispatch();
const booleanA = true;
const booleanB = false;
const [isOverMax, setIsOverMax] = useState(false);
const reset = () => {
dispatch(resetEditAction());
};
useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, isOverMax);
return [isOverMax, reset];
};

对于更多的上下文,booleanAbooleanB是由其他代码动态生成的,但即使像上面那样硬编码,isOverMax也只能是false。我永远无法得到一个真值,即使两个布尔值都硬编码为真。

状态isOverMax来源于booleanAbooleanB。因此,当booleanAbooleanB发生变化时,isOverMax也应该发生变化。您应该在依赖项数组中反映这一点。

useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, [booleanA, booleanB]);

下面是工作示例。只需点击"显示代码片段"即可。然后"运行代码段">

const useAlert = () => {
const [booleanA, setA] = React.useState(true);
const [booleanB, setB] = React.useState(false);
const [isOverMax, setIsOverMax] =React. useState(false);
const reset = () => {
setA(false);
setB(false);
};
React.useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, [booleanA , booleanB]);
// just for testing
const toggleA = () => {
setA((a) => !a);
}
return [isOverMax, reset, toggleA];
};
const App = () => {
const [alert, reset, toggleA]  = useAlert();
return <div>
isOverMax={"" + alert}<br/>
<button onClick={() => toggleA()} >Toggle A</button>
<button onClick={() => reset()} >Reset </button>
</div>;
};
ReactDOM.render(<App />, document.getElementById("root"));
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

由于状态booleanAbooleanB已经存在,当其中一个状态发生变化时,它们将触发渲染。因此,您可以只返回isOverMax

的计算结果。
const useAlert = () => {
// ...
return [booleanA || booleanB, reset];
}

const useAlert = () => {
const [booleanA, setA] = React.useState(true);
const [booleanB, setB] = React.useState(false);
const isOverMax = booleanA || booleanB;
const reset = () => {
setA(false);
setB(false);
};
// just for testing
const toggleA = () => {
setA((a) => !a);
}
return [isOverMax, reset, toggleA];
};
const App = () => {
const [alert, reset, toggleA]  = useAlert();
return <div>
isOverMax={"" + alert}<br/>
<button onClick={() => toggleA()} >Toggle A</button>
<button onClick={() => reset()} >Reset </button>
</div>;
};
ReactDOM.render(<App />, document.getElementById("root"));
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

编辑

是否有一般的准则,当不使用效果挂钩,所以我不开始扔它在代码中,它不是至关重要的?

没有,但是你应该读一下《钩子规则》。规则告诉你应该做什么来防止不可预测的行为。遗憾的是,他们没有解释这条规则的原因,这个问题不是解释这一切的地方。因此,如果你还有问题,请打开另一个问题。

useEffect的依赖项中删除isOverMax以避免无限循环

useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, []);

相关内容

  • 没有找到相关文章

最新更新