简体   繁体   English

如何防止React卸载/重新安装组件?

[英]How can I prevent React from unmounting/remounting a component?

I am using react-router and react-redux . 我正在使用react-routerreact-redux I have two routes like this: 我有两条这样的路线:

<Route path='/edit'     component={ EditNew } />
<Route path='/edit/:id' component={ EditDraft } />

where EditNew and EditDraft are data-providing containers that wrap an Editor component using the react-redux connect function: 其中EditNewEditDraft是使用react-redux connect函数包装Editor组件的数据提供容器:

const EditNew = connect(state => ({}))(React.createClass({
    render() {
        return <Editor />;
    }
}));

and

const EditDraft = connect(state => ({ drafts: state.drafts }))(React.createClass({
    render() {
        const { params, drafts } = this.props;
        const draft = findDraft(params.id, drafts);
        return <Editor draft={ draft } />;
    }
}));

Now, Editor is rigged up in such a way that when you begin typing into a blank Editor , it triggers a history.replaceState() from /edit to /edit/:id with a ranomly generated ID. 现在, Editor被装配成这样一种方式:当你开始输入空白的Editor ,它会触发一个history.replaceState()/edit/edit/:id并带有一个生成错误的ID。 When this happens, I get the following sequence of events: 发生这种情况时,我会得到以下事件序列:

  • EditorNew unmounts EditorNew卸载
  • Editor unmounts Editor卸载
  • EditorDraft renders and mounts EditorDraft渲染和安装
  • Editor renders and mounts Editor渲染和安装

When I coded these two containers, I thought that the Editor component contained in both of them would be reconciled without unmounting and remounting. 当我对这两个容器进行编码时,我认为两者中包含的Editor组件将在不卸载和重新安装的情况下进行协调。 This is problematic for me for several reasons besides the extra unnecessary work, chief among which are that the editor ends up losing focus and proper cursor range after the unmount and remount. 除了额外的不必要的工作之外,这对我来说是有问题的,其中主要的是编辑器在卸载和重新安装后最终失去焦点和正确的游标范围。

To no avail I have tried specifying key for the Editor component to hint to the reconciliation system that it's the same component, and I've tried shouldComponentUpdate , but that doesn't get called, which makes sense given what React is doing. 无济于事我尝试为Editor组件指定key以向协调系统提示它是同一个组件,并且我尝试过shouldComponentUpdate ,但是没有调用,这在React正在做的事情中是有意义的。

Apart from combining the two containers into one container with more complicated render() logic, is there anything I can do to prevent the Editor component from unmounting/remounting during the history transition? 除了将两个容器组合成一个具有更复杂的render()逻辑的容器之外,我还能做些什么来阻止Editor组件在历史转换期间卸载/重新安装?

React's Reconciliation Algorithm says that if the element has a different type (in this case, EditNew and EditDraft ), then React will “tear down the old tree and build the new tree from scratch.” React的Reconciliation算法表示,如果元素具有不同的类型(在本例中为EditNewEditDraft ),则React将“拆除旧树并从头开始构建新树”。

To prevent this, you need to use the same component for both routes. 为防止这种情况,您需要为两个路由使用相同的组件。

你可以使用shouldComponentUpdate ,如果路由已从/edit/edit/:id (你可以检查这是从连接到你的组件的状态获取路由器信息)返回false,所以它不会刷新组件。

Chances are that this isn't possible with react-router <= v3. react-router <= v3可能无法做到这一点。

With react-router v4, this should be possible now: https://github.com/ReactTraining/react-router/issues/4578 使用react-router v4,现在应该可以实现: https//github.com/ReactTraining/react-router/issues/4578

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM