防止在状态更改时反应路由卸载组件

时间:2019-01-21 14:01:06

标签: reactjs react-router

我正在使用react-router(v.4.3.1)渲染应用程序的主要部分,并且左侧有一个带有菜单的抽屉。当在应用程序标题中切换按钮时,我将更改折叠变量的状态,以使组件一致地重新渲染css。我的问题是,此变量需要存储在呈现我所有Route的组件上,并且在更新组件Route时要卸载并安装其组件。

我已经尝试向key提供一个Route,但是它不起作用。

我的代码如下所示,并且该组件的父级是正在更新的代码,它重新呈现了我的Main组件:

class Main extends Component {
    constructor(props) {
        super(props);
        this.observer = ReactObserver();
    }

    getLayoutStyle = () => {
        const { isMobile, collapsed } = this.props;
        if (!isMobile) {
            return {
                paddingLeft: collapsed ? '80px' : '256px',
            };
        }
        return null;
    };

    render() {
        const RouteWithProps = (({index, path, exact, strict, component: Component, location, ...rest}) =>
                <Route path={path}
                       exact={exact}
                       strict={strict}
                       location={location}
                       render={(props) => <Component key={"route-" + index} observer={this.observer} {...props} {...rest} />}/>
        );

        return (
            <Fragment>
                <TopHeader observer={this.observer} {...this.props}/>
                <Content className='content' style={{...this.getLayoutStyle()}}>
                    <main style={{margin: '-16px -16px 0px'}}>
                        <Switch>
                            {Object.values(ROUTES).map((route, index) => (
                                <RouteWithProps {...route} index={index}/>
                            ))}
                        </Switch>
                    </main>
                </Content>
            </Fragment>
        );
    }
}

我希望Route仅更新而不卸载组件。这可能吗?

1 个答案:

答案 0 :(得分:3)

由于在render方法内部定义了RouteWithProps,您遇到了这个问题。每次调用render方法时,这都会导致React卸载旧的并安装新的。实际上,在render方法中动态创建组件是一个性能瓶颈,被认为是不好的做法。

只需将RouteWithProps的定义移出Main组件即可。

近似的代码结构如下:

// your impors

const RouteWithProps = ({observer, path, exact, strict, component: Component, location, ...rest}) =>
     <Route path={path}
         exact={exact}
         strict={strict}
         location={location}
         render={(props) => <Component observer={observer} {...props} {...rest} />}/>;

class Main extends Component {
    ...

    render(){
        ...
        {Object.values(ROUTES).map((route, index) => (
            <RouteWithProps key={"route-" + index} {...route} observer={this.observer}/>
        ))}
                            ^^^ keys should be on this level
        ...
    }
}