提出问题
观察如下代码,我们需要依赖words
来更新自身,所以需要将words
加入useEffect
的依赖中。更新words
触发useEffect
,useEffect
再次更新words
,然后就产生了死循环。
function App() {
const [value, setValue] = useState('');
const [words, setWords] = useState([
{
id: 0,
text: 'like',
correct: false,
},
]);
useEffect(() => {
const items = value.split(' ');
// 我们需要用words来更新自身
const nextWords = words.map((word) => {
return {
...word,
correct: word.text === items[index],
};
});
setWords(nextWords);
}, [value, words]);
return (
<>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</>
);
}
分析问题
为了跳出useEffect
的死循环,问题的关键是,我们不能在useEffect
重更新依赖数组中的东西,否则必定产生死循环。那如何避免更新自己的依赖呢?答案是用一个新的变量来存储。
解决方案
我们创建了一个新的nextWords
来保存更新后的words
,避免了更新依赖项死循环的问题。
function App() {
const [value, setValue] = useState('');
const [words, setWords] = useState([
{
id: 0,
text: 'like',
correct: false,
},
]);
const [nextWords, setNextWords] = useState([])
useEffect(() => {
const items = value.split(' ');
// 我们需要用words来更新自身
const nextWords = words.map((word) => {
return {
...word,
correct: word.text === items[index],
};
});
// 这里不会导致死循环,因为nextWords并非依赖项
setNextWords(nextWords);
}, [value, words]);
return (
<>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</>
);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。