我最近一直在做一个 React 项目。我已经知道在文本框中键入时,React 会更新其 UI 状态并重新渲染文本框并将焦点带回它。整个过程发生得如此之快,以至于用户在键入时不会注意到文本框已重新呈现。
现在我的问题是,为什么 React 不只在 onChange 事件中更新文本框的 UI 状态并且不重新渲染文本框,因此不需要关注它。
为什么在这种情况或其他类似情况下不保存重新渲染过程。如果我们不重新渲染,我们会错过什么?
我最近一直在做一个 React 项目。我已经知道在文本框中键入时,React 会更新其 UI 状态并重新渲染文本框并将焦点带回它。整个过程发生得如此之快,以至于用户在键入时不会注意到文本框已重新呈现。
现在我的问题是,为什么 React 不只在 onChange 事件中更新文本框的 UI 状态并且不重新渲染文本框,因此不需要关注它。
为什么在这种情况或其他类似情况下不保存重新渲染过程。如果我们不重新渲染,我们会错过什么?
React 不会重新渲染元素,因为它会创建一个新元素来替换旧元素。在您的示例中,它只是更新值。
React 只会删除被另一种类型替换的元素。如果它是相同的类型,它只会更新丢失或更改的属性。您应该在官方文档中阅读有关Reacts Reconciliation 的内容。
不同类型的元素
每当根元素有不同的类型时,React 就会拆除旧树并从头开始构建新树。从
<a>
到<img>
,或从<Article>
到<Comment>
,或从<Button>
到<div>
- 这些中的任何一个都将导致完全重建。
相同类型的 DOM 元素
当比较两个相同类型的 React DOM 元素时,React 会查看两者的属性,保持相同的底层 DOM 节点,并且只更新更改的属性。
我在下面准备了一个演示。它是 React 与 jQuery 的结合,只是为了演示这一点。
如果每次 React 更新组件的状态值时都替换组件(即当我们在 textarea 中键入时),背景颜色将丢失,因为我们将讨论一个新创建的 DOM 元素。
但是,正如您所看到的,情况并非如此——背景保持不变。
class Greeting extends React.Component {
constructor() {
super();
this.state = {txt: ""};
}
updateTextarea = (e) => {
this.setState({txt: e.target.value});
}
render() {
return <textarea onChange={this.updateTextarea}>{this.state.txt}</textarea>;
}
}
ReactDOM.render(<Greeting />, document.getElementById('app'));
$("#btn").on("click", function() {
var colors = ["red", "green", "lightblue", "grey", "pink", "orange"];
var rand = Math.floor(Math.random() * 6);
$("#app textarea").css("background", colors[rand]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
<button id="btn">Randomize color!</button>