我的情况是这样的:
export default function Component({ navigation }) {
const [ item, setItem ] = useState([]);
useEffect(() => {
AsyncStorage.getItem('someItem')
.then(data => JSON.parse(data))
.then(jsonData => {
setItem(jsonData);
})
.catch(error => {});
}, [item]);
问题是 useEffect 似乎在循环中被调用,即使“item”没有改变。如果我从依赖项数组中删除 item,它只会被调用一次,并且当 item 更改时,组件不会重新渲染。有解决办法吗?
这样解决:
export default function Component({ navigation }) {
const [ item, setItem ] = useState([]);
const [ update, setUpdate ] = useState(false);
const handleUpdate = () => {
setUpdate(!update);
}
useEffect(() => {
AsyncStorage.getItem('someItem')
.then(data => JSON.parse(data))
.then(jsonData => {
setItem(jsonData);
})
.catch(error => {});
}, [update]);
然后在我想更新项目的状态时调用 handleUpdate(或将其传递给子组件并让子组件调用它)。
答案 0 :(得分:4)
你有一个无限循环:
您发送给 BigInteger
的第二个参数是依赖项数组。每次这些依赖项中的一个发生变化时 - 将调用 radix
的第一个参数,即回调。所以你这样做:
每次 useEffect()
更改 - 运行更改 useEffect()
的代码(因为回调将值设置为 item
)
注意:useEffect 也会首先调用一次发送给它的回调。
答案 1 :(得分:1)
问题与 this post 中描述的相同。当您使用对象作为依赖项时,useEffect
认为它在每次渲染时都不同。由于您使用的是一个数组,它是一个对象,因此您会得到无限循环。假设您的状态变量是一个原始类型,如字符串或数字,那么它不会继续呈现,因为 useEffect
将能够确定该值没有改变。
因此,在您的特定情况下可能的解决方案,因为有一个 JSON 字符串被返回,可以使用该 JSON 字符串作为并行状态变量来检查更改。
考虑这样的事情:
const simulateCall = () => Promise.resolve('["ds","1234sd","dsad","das"]')
export default function App() {
const [state, setArrayState] = React.useState([])
const [stringState, setStringState] = React.useState('')
React.useEffect(() => {
simulateCall()
.then(data => {
setStringState(data);
setArrayState(JSON.parse(data));
})
.catch(error => console.log(error));
}, [stringState]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{state.map((item, i) => <div key={i}>{item}</div>)}
</div>
);
}