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
How can I prevent React from unmounting/remounting a component?
提问by Dmitry Minkovsky
I am using react-routerand react-redux. I have two routes like this:
我正在使用react-router和react-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:
其中EditNew和EditDraft是Editor使用以下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。发生这种情况时,我会收到以下事件序列:
EditorNewunmountsEditorunmountsEditorDraftrenders and mountsEditorrenders 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.
无济于事我试图指定key的Editor组件提示和解制度,这是相同的组成部分,我已经试过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说,如果元素具有不同的类型(在本例中为EditNew和EditDraft),那么 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

