useState() 未在 useEffect() 挂钩内部更新
useState() not updating inside of useEffect() hook
我在更新 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];
};
对于更多上下文,booleanA
和 booleanB
是使用其他代码动态生成的,但即使像上面那样对它们进行硬编码,isOverMax
也只是 false
。我永远无法获得真正的价值,即使两个布尔值都被硬编码为 true。
删除 useEffect
的依赖项中的 isOverMax
以避免无限循环
useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, []);
状态 isOverMax
源自 booleanA
和 booleanB
。因此,只要 booleanA
或 booleanB
发生变化,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>
由于状态 booleanA
和 booleanB
已经存在,当其中一个状态改变时,它们将触发重新渲染。因此你可以 return 计算 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>
编辑
Are there any general guidelines for when NOT to use the effect hook so I don't start throwing it in code where it isn't crucial?
不一定,但你应该读过 Rules of Hooks。这些规则告诉您应该怎样做才能防止不可预测的行为。可悲的是,他们没有解释该规则的原因,这个问题是解释这一切的错误地方。因此,如果您还有一个问题,请打开另一个问题。
我在更新 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];
};
对于更多上下文,booleanA
和 booleanB
是使用其他代码动态生成的,但即使像上面那样对它们进行硬编码,isOverMax
也只是 false
。我永远无法获得真正的价值,即使两个布尔值都被硬编码为 true。
删除 useEffect
的依赖项中的 isOverMax
以避免无限循环
useEffect(() => {
setIsOverMax(booleanA || booleanB);
}, []);
状态 isOverMax
源自 booleanA
和 booleanB
。因此,只要 booleanA
或 booleanB
发生变化,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>
由于状态 booleanA
和 booleanB
已经存在,当其中一个状态改变时,它们将触发重新渲染。因此你可以 return 计算 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>
编辑
Are there any general guidelines for when NOT to use the effect hook so I don't start throwing it in code where it isn't crucial?
不一定,但你应该读过 Rules of Hooks。这些规则告诉您应该怎样做才能防止不可预测的行为。可悲的是,他们没有解释该规则的原因,这个问题是解释这一切的错误地方。因此,如果您还有一个问题,请打开另一个问题。