提供程序组件的 useEffect 在挂载之前正在运行



我有一个Provider组件,它通过其道具传递一些数据,稍后将在整个应用程序中使用。

它看起来像这样:

export const MyContext = createContext({});
MyContext.displayName = 'My Context';

export const MyProvider = ({ children }) => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const setData = async () => {
setLoading(true);
setItems(await getItemsApiCall());
setLoading(false);
};
useEffect(() => {
console.warn('component re-rendering')
if (!items.length) {
setData();
}
}, [items]);
return (
<MyContext.Provider value={{items, loading}}>
{children}
</MyContext.Provider>
);
};

理论上,这应该可以正常工作,但我看到通过console.warn进行了大量额外的重新渲染,这似乎是不必要的,而且我收到了与未安装组件的状态更新有关的警告

警告:无法对已卸载的组件执行React状态更新。这是一个非操作,但它表明您的应用程序中存在内存泄漏。。。

尽管我在其他线程中看到了这方面的解决方案,但它们都不适合我,因为我不仅设置了items,还设置了loading,在获取数据时,我需要将其放入应用程序其他部分的微调器和其他类似的东西中。

无论如何,在这种情况下,有没有办法防止这些在登山前再次出现,并发出警告?

编辑:记录在案,在更新未安装组件状态的警告之前,我目前正在进行两次重新渲染,然后进行另外两次重新呈现(这是意料之中的(。所以基本上,我的控制台看起来像这样:

组件重新渲染

组件重新渲染

警告:无法对未安装的组件执行React状态更新。这是一个非操作,但它表明您的应用程序中存在内存泄漏。。。

组件重新渲染

组件重新渲染

Edit2:值得一提的是,我也想展示一下MyProvider是如何使用的。它只是将另一个组件包装在特定的路线中。类似这样的东西:

const App = () => (
<Router>
<Switch>
<Route
path='/items'
exact
component={() => (
<MyProvider>
<Items/>
</MyProvider>
)}
/>
</Switch>
</Router>
)

我上面得到的行为只是在访问/items路由时发生的。

删除"项目";在setData中使用setItems时,从效果的依赖项列表中选择并接收回调。

最新更新