【发布时间】:2021-04-04 09:51:50
【问题描述】:
在 React 中,每次渲染/重新渲染组件时,它都会使用 createElement 重新生成它的所有子节点/组件。 React 如何知道何时在重新渲染之间保持组件状态?
例如,考虑以下代码:
class Timer extends Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
tick() {
this.setState(state => ({ seconds: state.seconds + 1 }));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return createElement('div', null,
'Seconds: ',
this.state.seconds
);
}
}
class Button extends Component {
constructor(props) {
super(props);
this.state = { clicks: 0 };
}
click() {
this.setState(state => ({ clicks: state.clicks + 1 }));
}
render() {
return createElement('button', { onClick: () => this.click() },
createElement(Timer, null),
'Clicks: ',
this.state.clicks
);
}
}
render(createElement(Button, null), document.getElementById('root'));
您可以使用 Preact REPL here 尝试此代码。
请注意,当按下按钮并更新 clicks 值时,Timer 组件的状态会保持不变并且不会被替换。 React 如何知道重用组件实例?
虽然一开始这似乎是一个简单的问题,但当您考虑更改传递给子组件的道具或子组件列表等问题时,它会变得更加复杂。 React 如何处理更改子组件的 props?即使子组件的道具发生了变化,它的状态是否仍然存在? (在 Vue 中,当组件的 props 发生变化时,组件的状态会持续存在)列表呢?当子组件列表中间的条目被删除时会发生什么?对这样的列表进行更改显然会生成非常不同的 VDOM 节点,但组件的状态仍然存在。
【问题讨论】:
-
createElement不会创建新组件。它返回一个描述(ReactElement)在该位置渲染哪个组件,具有哪些属性和子级。这是 react 用来确定组件树是否发生变化的。 -
知道这一点很有用,我目前正在阅读 React 的源代码以更好地了解他们的 VDOM 实现是如何工作的。
-
如果您发现任何关于他们的差异算法的见解(尤其是关于元素被认为“相同”与不同的情况),请确保post an answer yourself - 我也很好奇
-
“当一个组件更新时,实例保持不变,因此状态在渲染之间保持不变。” reactjs.org/docs/…
-
@FelixKling 我认为 OP 知道这一点,问题是 React 认为什么是更新,什么是新组件。
标签: javascript reactjs