【发布时间】:2020-08-24 19:11:39
【问题描述】:
我在 React FunctionComponent 中有以下模式的代码:
const MyComponent: React.FunctionComponent<ISomeInterface> = ({ someArray, someFunction }) => {
const [someStateObjVar, setSomeStateObjVar] = React.useState({});
const [isFound, setIsFound] = React.useState(false);
const handleSomeEvent = React.useCallback((someAttribute: string) => {
if (someAttribute) {
setSomeStateObjVar(someArray.find(
(arrayElement) => ( arrayElement.attribute === someAttribute )
);
setIsFound(someStateVar ?? false);
}
}
return ( isFound && someStateObjVar ) ? <FoundMatchingComponent /> ? <ComponentNotFound />;
在上面的代码中,someArray 元素总是与 someAttribute 匹配。 但问题是 MyComponent 总是呈现 ComponentNotFound 因为 isFound 总是在最后一行(return 语句)计算为 FALSE。
我能够通过以下重构解决此问题(插入一个中间变量,但总体逻辑保持不变):
const MyComponent: React.FunctionComponent<ISomeInterface> = ({ someArray, someFunction }) => {
const [someStateObjVar, setSomeStateObjVar] = React.useState({});
const [isFound, setIsFound] = React.useState(false);
const handleSomeEvent = React.useCallback((someAttribute: string) => {
let foundElement;
if (someAttribute) {
foundElement = someArray.find(
(arrayElement) => ( arrayElement.attribute === someAttribute )
);
}
if (foundElement) {
setSomeStateObjVar(foundElement);
setIsFound(true);
}
}
return ( isFound && someStateObjVar ) ? <FoundMatchingComponent /> ? <ComponentNotFound />;
使用此第二版代码,isFound 在最后一行正确地计算为 TRUE,并且 MyComponent 正确地呈现 FoundMatchingComponent。
您能否解释一下为什么第一个版本不起作用,而第二个版本起作用?
我的猜测是,第二个版本中的中间变量为 React 提供了足够的时间在 return 语句中正确评估 isFound 变量,但我不确定这就是解释。任何关于改进我上面的代码的建议也将不胜感激。谢谢。
【问题讨论】:
-
在第一个代码中,您调用
setState()太早了,因为在 React 中,状态不会立即更新。由于isFound取决于第一个状态,因此您必须使用useEffect在设置isFound之前观察第一个状态何时发生变化,或者像您已经在做的那样使用您的第二个解决方案。 -
谢谢@IsraelObanijesu,你是对的。我需要记住,设置状态变量不会立即更新,而是由 React 批处理。此外,您能否提供有关如何使用 useEffect 解决原始问题的更多详细信息。我不确定我是否遵循您的建议,但很想知道。谢谢
标签: javascript reactjs typescript usecallback