反应 useEffect 警告以放置缺少的依赖项。但是钩子中的依赖值发生了变化
Posted
技术标签:
【中文标题】反应 useEffect 警告以放置缺少的依赖项。但是钩子中的依赖值发生了变化【英文标题】:React useEffect warning to put missing dependency. But dependency value changes in the hook 【发布时间】:2020-11-13 03:35:43 【问题描述】:我想在 step 的值改变时改变 formStepTouched 的值,所以我使用了 useEffect。但是 useEffect 会抛出一个警告,指出它缺少对 formStepTouched 的依赖。因为那是正在改变的值,把它放在依赖数组中会导致无限调用。
const [step, setStep] = useState(0);
const [formStepTouched, setFormStepTouched] = useState(
Array(childrenArray.length)
.fill(false)
.map((_, idx) => idx === 0)
)
useEffect(() =>
const newFormStepTouched = [...formStepTouched];
newFormStepTouched[step] = true;
setFormStepTouched(newFormStepTouched);
, [step]);
请参考下面的代码框链接: https://codesandbox.io/s/brave-gould-ymjt0?file=/src/App.js
正如您所见,演示运行良好,但显示了一条错误消息。如果添加了依赖,useEffect 将被无限调用。
如何摆脱错误信息。
【问题讨论】:
上面的sn-p中useState是否缺少右括号? 能否请您在代码框内提供一个示例? 是的,右括号丢失,已修复。添加了与代码框演示的链接。 【参考方案1】: useEffect(() =>
setFormStepTouched(prevState =>
const newFormStepTouched = [...prevState]
newFormStepTouched[step] = true
return newFormStepTouched
);
, [step]);
linter 告诉你有一个外部依赖可能会改变,你可以阅读更多here
【讨论】:
这会改变formStepTouched
并且不会重新渲染组件。【参考方案2】:
您可以将回调传递给状态设置器:
const useEffect, useState = React;
const App = () =>
const [step, setStep] = useState(0);
const [formStepTouched, setFormStepTouched] = useState(
Array(5)
.fill(false)
.map((_, idx) => idx === 0)
);
useEffect(() =>
//pass a callback to state setter
setFormStepTouched((formStepTouched) =>
if (formStepTouched[step] === true)
//nothing to change
return formStepTouched;
return formStepTouched.map((s, i) =>
i === step ? true : s
);
);
, [step]);
return (
<div>
<button onClick=() => setStep(step + 1)>
nex step
</button>
<div>
<pre>
JSON.stringify(formStepTouched, undefined, 2)
</pre>
</div>
</div>
);
;
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
【讨论】:
我可能错了,但这不会改变状态。如果你传递一个回调,像这样改变状态是否可以? @dracarys 如果您在沙箱中尝试,现在删除的带有prevState[step] = true
的答案将改变状态,您会看到 steps 数组比当前 step 落后一步,因为该效果不会导致组件重新使成为。数组映射创建一个新数组并且不会发生变异。你也可以const copy = [...current]; copy[step]=true;return copy;
。
感谢您的解释,但我不确定我是否完全理解。 formStepTouched 仍然指向内存中的相同位置,对吗?还是因为它是在参数中传递的,React 内部会处理它并传递一个指向不同位置的参数?
@dracarys 你认为我在哪一行改变了formStepTouched
?
我刚刚又浏览了一遍你的代码,我不认为你是,我之前弄糊涂了。感谢您的帮助。以上是关于反应 useEffect 警告以放置缺少的依赖项。但是钩子中的依赖值发生了变化的主要内容,如果未能解决你的问题,请参考以下文章
如何绕过 React 的 useEffect() “缺少依赖项”警告?
我收到一个奇怪的警告“React hook useEffect 缺少依赖项”
如何解决此警告:“React Hook useEffect 缺少依赖项:'history'”?
useEffect 在自定义钩子中使用 ref 缺少依赖项警告