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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33151563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:10:29  来源:igfitidea点击:

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

javascriptreactjs

提问by Dmitry Minkovsky

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

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

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

where EditNewand EditDraftare data-providing containers that wrap an Editorcomponent using the react-reduxconnectfunction:

其中EditNewEditDraftEditor使用以下react-reduxconnect函数包装组件的数据提供容器:

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, Editoris rigged up in such a way that when you begin typing into a blank Editor, it triggers a history.replaceState()from /editto /edit/:idwith a ranomly generated ID. When this happens, I get the following sequence of events:

现在,Editor以这样一种方式被操纵,当你开始输入一个空白时Editor,它会触发一个history.replaceState()from /editto/edit/:id和一个随机生成的 ID。发生这种情况时,我会收到以下事件序列:

  • EditorNewunmounts
  • Editorunmounts
  • EditorDraftrenders and mounts
  • Editorrenders and mounts
  • EditorNew卸载
  • Editor卸载
  • EditorDraft渲染和安装
  • Editor渲染和安装

When I coded these two containers, I thought that the Editorcomponent 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.

在我对这两个容器进行编码时,我以为它们中Editor包含的组件将被协调,而无需卸载和重新安装。这对我来说是有问题的,除了额外的不必要工作之外,还有几个原因,其中主要是编辑器在卸载和重新安装后最终失去焦点和正确的光标范围。

To no avail I have tried specifying keyfor the Editorcomponent 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.

无济于事我试图指定keyEditor组件提示和解制度,这是相同的组成部分,我已经试过shouldComponentUpdate,但不会被调用,这使得给什么反应,是做的感觉。

Apart from combining the two containers into one container with more complicated render()logic, is there anything I can do to prevent the Editorcomponent from unmounting/remounting during the history transition?

除了将两个容器合并为一个render()逻辑更复杂的容器之外,我还能做些什么来防止Editor组件在历史转换期间卸载/重新安装?

采纳答案by Thai

React's Reconciliation Algorithmsays that if the element has a different type (in this case, EditNewand EditDraft), then React will “tear down the old tree and build the new tree from scratch.”

React 的 Reconciliation Algorithm说,如果元素具有不同的类型(在本例中为EditNewEditDraft),那么 React 将“拆除旧树并从头开始构建新树”。

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

为了防止这种情况,您需要为两条路线使用相同的组件。

回答by Franco Risso

You can use shouldComponentUpdateand, if the route has changed from /editto /edit/:id(you can check this getting the router info from the state connected to your component) return false, so it won't refresh the component.

您可以使用shouldComponentUpdateand,如果路由已更改/edit/edit/:id(您可以检查从连接到组件的状态获取路由器信息)返回 false,因此它不会刷新组件。

回答by amann

Chances are that this isn't possible with react-router<= v3.

使用react-router<= v3 时,这可能是不可能的。

With react-routerv4, this should be possible now: https://github.com/ReactTraining/react-router/issues/4578

使用react-routerv4,现在应该可以了:https: //github.com/ReactTraining/react-router/issues/4578