通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

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

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

受控组件与非受控组件主要区别在于数据管理的方式。受控组件是由React的状态(state)控制其值、事件处理是通过回调函数来进行的、而非受控组件则是直接通过DOM本身来管理数据。在受控组件中,表单数据是由React组件来管理的,每当表单元素的状态变化时,例如输入框的内容发生改变,都会触发一个函数来更新组件的状态。而非受控组件,相反,是DOM本身保持状态,我们通过ref来从DOM中获取表单数据。

在受控组件中,React充分扮演了中介的角色。因为状态的一切变化都被React的setState所管理,这使得状态的追踪和数据的验证变得更加方便。例如,我们可以随时根据用户的输入对用户的输入进行控制,限制用户只能输入特定格式的数据。

一、受控组件的工作原理

受控组件主要通过状态(state)来管理表单元素(如<input><textarea><select>)。表单元素在受控组件中的值是由React状态决定的。每当表单元素发生变化时,例如用户输入,就会调用一个事件处理函数,这个函数会根据输入更新组件的状态。因为表单元素的值是直接从组件的状态中读取的,所以表单元素会随组件状态的变化而变化。

1. 事件处理与状态更新

在受控组件中,每个表单元素都有一个对应的事件处理函数来响应用户的输入。当用户在输入框中键入字符时,这个事件处理函数将被触发,然后调用setState来更新组件状态。由于React状态是可预测的,我们总能够知道表单元素的当前值。

2. 双向数据绑定

双向数据绑定是指表单元素的值和组件状态之间的同步更新。在受控组件中,我们通常会将<input>元素的value属性设置为与状态相关联的值,并且当用户输入时,通过事件处理函数更新这个值。

二、非受控组件的工作原理

与受控组件不同,非受控组件不使用状态来管理表单元素的值。在非受控组件中,表单数据由DOM节点本身管理。代替事件处理函数,我们使用Ref来直接从DOM获取值。

1. 使用Ref访问DOM元素

在非受控组件中,我们通过创建一个ref(使用React.createRef())并将其赋值给表单元素的ref属性来获取对表单元素的直接访问权。之后,我们可以在需要时,通过ref访问DOM元素,从而获取或设置表单元素的实际值。

2. 非受控组件的优势与用途

非受控组件在某些情况下比受控组件更为简单高效。如果你的表单需要在提交时才处理输入值,那么非受控组件是一个较好的选择,因为它避免了每次输入时更新组件状态的开销。

三、何时使用受控组件

通常情况下,如果需要实施实时的校验、确保输入格式的正确性、或者当表单的输入与组件的状态紧密相关时,使用受控组件会是更好的选择。

1. 验证用户输入

受控组件允许我们在用户输入时就立即进行反馈,并且可以阻止不符合要求的输入。这对于保证用户填写的数据符合特定格式非常有帮助。

2. 依赖表单值的复杂逻辑

如果表单输入将触发复杂的逻辑,如输入推演或数据预处理,受控组件可以提供更高的灵活性和控制力。

四、何时使用非受控组件

当你不需要实时监控用户输入或者是单一的表单提交操作时,非受控组件提供了一种更简练且性能更优的处理方式。

1. 提交时处理表单数据

如果仅需要在用户提交表单时处理数据,而在输入过程中不需要即时的状态更新或验证,则非受控组件是一个很好的选择。

2. 减少不必要的渲染

由于非受控组件不依赖于组件状态的变化来更新表单元素的值,因此它避免了在输入过程中可能发生的多余渲染。

五、实现示例

以下是在React应用中创建受控组件和非受控组件的简单示例代码。

1. 受控组件示例代码

class ControlledForm extends React.Component {

constructor(props) {

super(props);

this.state = { value: '' };

this.handleChange = this.handleChange.bind(this);

this.handleSubmit = this.handleSubmit.bind(this);

}

handleChange(event) {

this.setState({value: event.target.value});

}

handleSubmit(event) {

alert('A name was submitted: ' + this.state.value);

event.preventDefault();

}

render() {

return (

<form onSubmit={this.handleSubmit}>

<label>

Name:

<input type="text" value={this.state.value} onChange={this.handleChange} />

</label>

<input type="submit" value="Submit" />

</form>

);

}

}

2. 非受控组件示例代码

class UncontrolledForm extends React.Component {

constructor(props) {

super(props);

this.handleSubmit = this.handleSubmit.bind(this);

this.input = React.createRef();

}

handleSubmit(event) {

alert('A name was submitted: ' + this.input.current.value);

event.preventDefault();

}

render() {

return (

<form onSubmit={this.handleSubmit}>

<label>

Name:

<input type="text" ref={this.input} />

</label>

<input type="submit" value="Submit" />

</form>

);

}

}

六、最佳实践

在决定使用受控组件还是非受控组件时,应考虑应用的需求和目标。最佳实践建议是尽可能使用受控组件,因为它们提供了更好的数据管理和界面一致性。但在某些性能要求较高或者对数据处理有特定时机要求的场合,使用非受控组件也是合理的选择。

1. 合理使用ref

对于非受控组件,在使用ref时要谨慎,避免过度使用。虽然ref有其用武之地,但在大多数情况下,通过状态和属性(props)来进行数据管理是更好的选择。

2. 表单性能优化

当处理巨大和复杂的表单时,非受控组件因为减少了不必要的状态更新,可能有助于提高应用的性能。

总而言之,掌握受控组件与非受控组件的使用时机和管理方式,可以有效地在React中构建稳健且易于维护的用户表单。

相关问答FAQs:

Q: React中的受控组件和非受控组件有什么区别?

A: 受控组件和非受控组件在React中是两种管理表单输入的方式。受控组件通过state来控制输入的值,而非受控组件则将输入的值交给DOM处理。

Q: 如何选择使用受控组件还是非受控组件?

A: 选择使用受控组件还是非受控组件可以根据需要来决定。如果希望获取用户输入的值并进行处理,或者在用户输入时进行验证,那么可以选择受控组件。如果只是需要简单地获取表单的值,或者处理大量输入时,可以选择非受控组件。

Q: 在React中如何实现受控组件和非受控组件?

A: 实现受控组件可以通过在组件的state中保存输入的值,并在输入变化时更新state。然后通过设置input元素的value属性和onChange事件来与state绑定。实现非受控组件可以通过给input元素设置一个ref属性来获取输入的值,然后通过编程方式处理该值。在非受控组件中,可以使用defaultValue属性设置初始值。

相关文章