考虑依赖于两个异步调用的组件的状态。一个是初始呼叫,另一个是重复呼叫。
两者都更改由useState
控制的数组。通过将旧数组散布到文字中来附加数组。
问题是当两个调用都解析它们设置相同的状态时,但是与旧数组的传播是从调用useEffect
开始的作用域查找。因此,其中一个调用总是“覆盖”另一个。
这是一些简化的代码:
const Component = () => {
const location = useLocation()
const [numbers, setNumbers] = useState([1,2,3])
// say this returns [4,5,6]
useEffect(()=>{
fetchOnce().then(newNumbers => setNumbers([...numbers, newNumbers]))
}, [])
// say this returns [7,8,9]
useEffect(()=>{
fetchMultiple().then(newNumbers => setNumbers([...numbers, newNumbers]))
}, [location])
}
最终结果是[1,2,3,4,5,6]或[1,2,3,7,8,9]。
如何更改它以便正确设置状态? 我应该是[1,2,3,4,5,6,7,8,9]或[1,2,3,7,8,9,4,5,6]。
答案 0 :(得分:2)
改为使用setNumbers
的回调形式:
const Component = () => {
const location = useLocation()
const [numbers, setNumbers] = useState([1,2,3])
// say this returns [2,3,4]
useEffect(()=>{
fetchOnce().then(newNumbers => setNumbers(numbers =>[...numbers, ...newNumbers]));
}, [])
// say this returns [5,6,7]
useEffect(()=>{
fetchMultiple().then(newNumbers => setNumbers(numbers => [...numbers, ...newNumbers]))
}, [location])
}
const { useState, useEffect } = React;
const fetchOnce = () => Promise.resolve([2, 3, 4]);
const fetchMultiple = () => Promise.resolve([5, 6, 7]);
console.error = () => void 0; // suppress key warning, not sure what OP wants for keys
const Component = () => {
const [numbers, setNumbers] = useState([1,2,3])
useEffect(()=>{
fetchOnce().then(newNumbers => setNumbers(numbers =>[...numbers, ...newNumbers]));
}, [])
useEffect(()=>{
fetchMultiple().then(newNumbers => setNumbers(numbers => [...numbers, ...newNumbers]))
}, [location])
return (
<div>
{numbers.map(number => <div>{number}</div>)}
</div>
);
}
ReactDOM.render(<Component />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class="react"></div>