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

问题描述:

我正在使用 react-router react-redux 。我有两条这样的路线:

I am using react-router and react-redux. I have two routes like this:

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

其中 EditNew EditDraft 是使用 react-redux 包装编辑器组件的数据提供容器 connect function:

where EditNew and EditDraft are data-providing containers that wrap an Editor component using the react-redux connect function:

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

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 } />;
    }
}));

现在,编辑就是这样的当你开始输入空白的编辑器时,它会从 history.replaceState() $ c> / edit 到 / edit /:id 带有一个生成错误的ID。发生这种情况时,我会得到以下事件序列:

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. When this happens, I get the following sequence of events:


  • EditorNew unmounts

  • 编辑卸载

  • EditorDraft 渲染和坐骑

  • 编辑渲染和坐骑

  • EditorNew unmounts
  • Editor unmounts
  • EditorDraft renders and mounts
  • Editor renders and mounts

当我对这两个容器进行编码时,我认为两者中包含的编辑器组件将在不卸载和重新安装的情况下进行协调。除了额外的不必要的工作之外,这对我来说是有问题的,其中主要的是编辑器在卸载和重新安装后最终失去焦点和正确的游标范围。

When I coded these two containers, I thought that the Editor component contained in both of them would be reconciled without unmounting and remounting. 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.

无效我尝试为编辑$ c $指定 c>组件向协调系统提示它是同一个组件,我已经尝试过 shouldComponentUpdate ,但是没有调用它,这是有意义的,因为React是什么做。

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.

除了将两个容器组合成一个具有更复杂的 render()逻辑的容器外,还有什么我可以阻止编辑组件在历史转换期间卸载/重新安装?

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?

React的调节算法说如果元素有不同类型(在这种情况下, EditNew EditDraft ),然后React将拆除旧树并构建新的树从头开始。

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."

为了防止这种情况,你需要使用s两条路线的ame组件。

To prevent this, you need to use the same component for both routes.