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-router
and react-redux
. I have two routes like this:
我正在使用react-router
和react-redux
。我有两条这样的路线:
<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:
其中EditNew
和EditDraft
是Editor
使用以下react-redux
connect
函数包装组件的数据提供容器:
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. When this happens, I get the following sequence of events:
现在,Editor
以这样一种方式被操纵,当你开始输入一个空白时Editor
,它会触发一个history.replaceState()
from /edit
to/edit/:id
和一个随机生成的 ID。发生这种情况时,我会收到以下事件序列:
EditorNew
unmountsEditor
unmountsEditorDraft
renders and mountsEditor
renders and mounts
EditorNew
卸载Editor
卸载EditorDraft
渲染和安装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. 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 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.
无济于事我试图指定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 Editor
component 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, EditNew
and 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 shouldComponentUpdate
and, if the route has changed from /edit
to /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.
您可以使用shouldComponentUpdate
and,如果路由已更改/edit
为/edit/:id
(您可以检查从连接到组件的状态获取路由器信息)返回 false,因此它不会刷新组件。
回答by amann
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