使用效果在状态更改时不运行



我有一个屏幕(MyPics.js(,显示用户从另一个屏幕中选择的图像集合。我从异步存储中获取选定的图像。

如果我选择图像然后重新启动模拟器,一切正常。当我导航到 MyPics.js 屏幕时,我看到以前选择的图像中存储在 AsyncStorage 中的所有图像。

const MyPicsScreen = props => {
const [picList, setpicList] = useState([]);
useEffect(() => {
console.log("I'm in!! picList data is: " +  picList);
AsyncStorage.getItem("mypics").then((response) => {
const currentData = JSON.parse(response);
setpicList(currentData);
console.log("Current picList data will be: " + currentData);
});
}, []);

return (
<View style={styles.wrapper}>
<ScrollView>
<View style={{flexDirection: "column", justifyContent: "center", alignItems: "center"}}>
{picList ? picList.map((item, index) => {
return (
<View key={index} style={styles.viewItem}>
<Image style={{width: 200, height: 131}} source={Images[PicList[item][3]]} />
</View>
);
}
) : <View><Text>You haven't selected any pics yet</Text></View>}
</View>
</ScrollView>
</View>
);
};

终端显示:

I'm in!! picList data is:  //No data, as expected. Nothing is retrieved yet, then...
Current picList data: pic001,pic007,pic099 // That shows, correctly, what's stored and screen shows those images 

但是,如果我添加图像,除非重新启动模拟器,否则新图像不会显示。另外,控制台中没有读出,因此 useEffect 不会运行以获取数据并重置状态。

我假设返回MyPics屏幕会导致重新渲染,但我可能是错的。

我在 MyPics .js屏幕上制作了 3 个按钮,这些按钮在异步存储上手动运行 removeItem 或 setItem 或 getItem,然后删除或设置或获取图像,然后更新 picList 状态。

这行得通。

当我使用按钮时,它会获取或删除以前设置的图像或设置新图像,并且屏幕重新渲染以显示状态更改。

因此,当我导航到MyPics.js屏幕时,useEffect没有运行。它仅在第一次渲染上运行。

当我添加 picList 状态作为依赖项时,

}, [picList]);

它可以工作,但控制台在无限循环中运行。

这正常吗?我应该忽略无限滚动控制台还是错过了一个步骤?我是否应该使用焦点侦听器在重新访问时重新呈现页面,因为我只需要返回 MyPics 屏幕时的新数据。

来自文档

如果要运行效果并仅清理一次(在装载和 卸载(,您可以将空数组 ([]( 作为第二个参数传递。这 告诉 React 你的效果不依赖于 props 的任何值 或状态,因此它永远不需要重新运行。这不会作为特殊处理 case — 它直接遵循依赖数组始终如何 工程。

因此,将空数组传递给您的useEffect大致等同于(除了初始绘制触发useEffect类组件的componentDidMountcomponentWillUnmount函数。

经过很多痛苦和浪费的时间,这有效:

useEffect(() => {
AsyncStorage.getItem("mypics").then((response) => {
setpicList(JSON.parse(response);
});
}, []);
const getList = useCallback(() => {
AsyncStorage.getItem("mypics").then((value) =>{
setpicList(JSON.parse(value));
});
}, [picList]);

在这个线程中可以找到一些非常实用的功能组件示例:

React 导航 didfocus 事件侦听器在类组件和功能组件之间的工作方式不同

返回屏幕时需要焦点检测,以便 useEffect 函数再次运行。

感谢 @Kelvin Aitken 和 @Danny Buonocore 的支持

我想知道为什么useEffect钩子只在初始加载期间工作,并且每当我尝试分页更多项目时都会失败。

我后来发现我应该在[]中传递任何依赖项/状态,以告诉钩子随时渲染状态更改。


const [fetchItemInput, SetFetchItemInput] = useState(input);
const fetchMoreItemBtn = (nextCursor) => {
const newInput = { ...fetchItemInput };
newInput.after = nextCursor;
return SetFetchItemInput(newInput);
};
useEffect(() => {
handleFetchItem(fetchItemInput)
.then((res) => {
...
})
.catch((error) => {
...
});
return () => {};
}, [fetchItemInput]);       // Any changes run the effect

再次感谢您的支持。

相关内容

  • 没有找到相关文章

最新更新