React 中的受控组件与非受控组件

IT技术 javascript reactjs
2021-03-17 12:58:24

几乎在每个 ReactJS 教程中,甚至在处理输入更改的官方文档中,都推荐使用 onChange。我们为值使用状态并通过 onChange 更改它。这会在每次击键时触发渲染。所以,

  1. 渲染真的那么便宜吗?
  2. 输入值是否未保存在 DOM 中?所以 DOM 和 VirtualDOM 之间没有区别,所以虽然渲染发生了什么变化?(可能是错误的假设)。

只是为了好玩和学习的目的,我尝试了这些:

  1. 使用自定义函数和变量来保存值,在最后一次输入后设置状态,而不是在每次击键时,传递该值相关组件等。
  2. 使用 onBlur 而不是 onChange。

但是,我不喜欢他们中的任何一个,并且想问这个问题。如果实时输入值更改对我们来说不重要,我们只关心最后一个输入,那么 onChange 仍然是要走的路吗?

2个回答

React 非常有效地处理重新渲染。它只重新渲染更改。

有两种配置输入的方法

第一:受控输入

对于受控输入,您通常使用状态变量(或在某些情况下甚至是props)指定输入的值。在这种情况下,您需要调用 onChange 函数来设置状态(或props),因为值设置为状态/props,您需要更改它以更改值,否则它将保持不变。

前任

<input value={this.state.textVal} onChange={(e) => this.setState({textVal: e.target.value}) />

拥有受控输入的优点是您可以在整个 React 组件中使用值,并且您不需要在输入时触发事件或访问 DOM 来获取值。

第二:不受控制的输入

在这种情况下,您不需要 onChange 处理程序来获取输入,因为您没有为输入指定自定义值。可以通过访问 dom 或从事件对象获取输入的值

前任:

<input type="text" onBlur={(e) => {console.log(e.target.value)}/>

获取输入值的另一种方法是访问我们使用 refs 作为的 DOM this.inputVal.value

请参阅有关如何使用 ref 的答案:

在 React .js 中:是否有任何类似于 javascript 中的 document.getElementById() 的函数?如何选择某个对象?

关于你关于 React virtualDOM 的问题

虚拟 DOM 用于高效地重新渲染 DOM。这与脏检查您的数据并没有真正的关系。您可以使用带有或不带有脏检查的虚拟 DOM 重新渲染。计算两个虚拟树之间的差异有一些开销,但虚拟 DOM 差异是关于了解 DOM 中需要更新的内容,而不是您的数据是否已更改。

只有在状态改变时才会重新渲染虚拟树。因此,使用 observable 来检查状态是否已更改是防止不必要的重新渲染的有效方法,这会导致许多不必要的树差异。

如果您指的是虚拟树,则它表示为防止重新渲染而进行的脏检查
2021-04-24 12:58:24
我错过了文档中不受控制的部分,感谢您指出这一点。使用 ref 这很容易,正如我所见。但是,在您的回答和@squegeim 关于“单一来源的真相”的解释之后,我看到 onChange 是去。最后一件事,由于我是一名学习者,您能否向我展示有关使用有关该主题的 observable 的“文档”?
2021-05-04 12:58:24
我当然会接受它。说 observable 是指不受控制的组件吗?
2021-05-07 12:58:24
不,您应该使用受控组件,有一个链接与受控组件相同的文档。
2021-05-13 12:58:24
我现在已经在使用受控组件,我只是问了这个问题以更好地理解。我只是不明白你的回答中“使用可观察的......”部分。
2021-05-15 12:58:24

对我来说,除了实时验证之外,使用受控组件的主要原因是“单一数据源”的原则。

对于不受控制的组件,表单输入和 React 组件中使用的输入值可能不同。您可以获取新值onBlur,但有一些方法可以在不发出此事件的情况下更改 DOM 中的值,在这种情况下,用户看到的值和您正在处理的值可能不同,从而导致不同的结果用户期望什么。

这可能不是一个大问题,但是由于 React 经常宣扬这个原则(比如不将值保持在可以从其他状态派生的状态中),我只是为了一致性而这样做。

此外,您无需担心重新渲染每个输入的成本。

谢谢你提醒我Single Source of Truth。在我成为开发人员的路上,我真的应该经常记住这一点:) 对于一个非常非常大的应用程序,重新渲染仍然不是问题吗?或者开发人员用其他一些东西来解决这个问题?像@Shubham Khatri 的可观察建议,或者在 React 的生命周期中,或者其他方式?
2021-04-23 12:58:24