React 和 Redux componentWillMount 和 componentDidMount <Provider> Vs 订阅防止内存泄漏

问题描述

我的应用程序出现问题,该应用程序使用 Provider 方法在整个应用程序中更新状态。浏览器的控制台会抛出警告,因为在单击事件上使用 react-router-dom 重定向到另一个组件的 react 组件也在分派一个 action,而第二个组件已经安装。

index.js:1 警告:无法对已卸载的对象执行 React 状态更新 成分。这是一个空操作,但它表明您的内存泄漏 应用。修复,取消所有订阅和异步任务 在 componentwillUnmount 方法中。

这是代码。主要组件是详细信息和结果,当我在浏览器中从一个切换到另一个时会出现警告。

https://github.com/juampablotoledo/prueba-redux.git

这是我的 index.js

import React from "react";
import ReactDom from "react-dom";
import { Provider } from "react-redux";
import { browserRouter,Route,Redirect,Switch } from "react-router-dom";
import Results from "./components/results";
import Details from "./components/details";
import store from "./redux/store";

const Root = (
    <Provider store={store}>
        <browserRouter>
            <Switch>
                <Route path="/results">
                    <Results />
                </Route>
                <Route path="/details/:itemId">
                    <Details />
                </Route>
                <Redirect from="/" to="/results" />
            </Switch>
        </browserRouter>
    </Provider>
);

ReactDom.render(Root,document.getElementById("root"));

我已经阅读了几篇关于取消订阅操作以防止出现此类问题的帖子,但我不知道 Provider 组件是否可以与订阅一起存在。

解决方法

我更改了组件树,现在似乎可以正常工作了。

AppBar 组件位于Details 组件和Results 组件的内部,当react-router-dom 在它们之间切换时,Autocomplete 组件(AppBar 的孙子)每次都在毫秒内挂载和卸载。

>

许多逻辑发生在 Autocomplete 内部,包括动作触发器和 对全局状态进行了几次查询,因此最好让它从一开始就一直加载。

我更改了 index.js,因此 AppBar 组件只能呈现一次,并防止其他组件在用户触摸 UI 时挂载和卸载应用逻辑。

import React from "react";
import ReactDom from "react-dom";
import { Provider } from "react-redux";
import { BrowserRouter,Route,Redirect,Switch } from "react-router-dom";
import Results from "./components/results";
import Details from "./components/details";
import AppBar from "./components/appBar";

import store from "./redux/store";

const Root = (
    <Provider store={store}>
        <BrowserRouter>
            <Switch>
                <Route path="/results">
                    <AppBar />
                    <Results />
                </Route>
                <Route path="/details/:itemId">
                    <AppBar />
                    <Details />
                </Route>
                <Redirect from="/" to="/results" />
            </Switch>
        </BrowserRouter>
    </Provider>
);