深入理解React中的受控组件与非受控组件

288 阅读2分钟

在现代前端开发中,表单处理是一个不可或缺的部分。无论是学习Vue还是React,理解如何高效地处理表单数据是非常重要的。本文将带你深入了解React中的受控组件和非受控组件,帮助你更好地掌握前端表单开发。

受控组件

在React中,受控组件是指那些其数据由React组件的状态(state)管理的表单元素。这意味着,任何表单元素的值都可以通过组件的状态来追踪和控制。

为什么使用受控组件?

  1. 数据一致性:受控组件可以确保表单数据与组件状态之间的一致性。
  2. 状态管理:可以轻松地在组件中管理表单数据。
  3. 事件处理:可以自定义事件处理逻辑,如输入验证、数据格式化等。

受控组件的基本使用

import React from "react";
​
class App extends React.Component {
  state = {
    value: ""
  }
​
  handleChange = (e) => {
    this.setState({
      value: e.target.value
    });
  }
​
  clickHandle = () => {
    console.log(`你要提交的内容为:${this.state.value}`);
  }
​
  render() {
    return (
      <div>
        <input type="text" value={this.state.value} onChange={this.handleChange} />
        <button onClick={this.clickHandle}>提交</button>
      </div>
    );
  }
}
​
export default App;

对用户输入的内容进行限制

import React from "react";
​
class App extends React.Component {
  state = {
    value1: "",
    value2: ""
  }
​
  handleChange = (e) => {
    const name = e.target.name;
    switch (name) {
      case "one":
        this.setState({
          value1: e.target.value.toUpperCase()
        });
        break;
      case "two":
        const newValue = e.target.value.split("").map(item => {
          if (!isNaN(item)) {
            return item;
          }
        }).join("");
        this.setState({
          value2: newValue
        });
        break;
    }
  }
​
  clickHandle = () => {
    console.log(`你要提交的内容为:${this.state.value}`);
  }
​
  render() {
    return (
      <div>
        <input
          type="text"
          name="one"
          value={this.state.value1}
          onChange={this.handleChange}
          placeholder="自动转为大写"
        />
        <input
          type="text"
          name="two"
          value={this.state.value2}
          onChange={this.handleChange}
          placeholder="只能输入数字"
        />
        <button onClick={this.clickHandle}>提交</button>
      </div>
    );
  }
}
​
export default App;

文本域

import React from "react";
​
class App extends React.Component {
  state = {
    value: ""
  }
​
  handleChange = (e) => {
    this.setState({
      value: e.target.value
    });
  }
​
  clickHandle = () => {
    console.log(`你要提交的内容为:${this.state.value}`);
  }
​
  render() {
    return (
      <div>
        <textarea
          cols="30"
          rows="10"
          value={this.state.value}
          onChange={this.handleChange}
        />
        <button onClick={this.clickHandle}>提交</button>
      </div>
    );
  }
}
​
export default App;

多选框

import React from "react";
​
class App extends React.Component {
  state = {
    checkBoxs: [
      { content: "html", checked: false },
      { content: "css", checked: false },
      { content: "js", checked: false },
      { content: "vue", checked: false },
      { content: "react", checked: false },
    ],
  }
​
  handleChange = (index) => {
    const arr = [...this.state.checkBoxs];
    arr[index].checked = !arr[index].checked;
    this.setState({
      checkBoxs: arr
    });
  }
​
  clickHandle = () => {
    console.log(this.state.checkBoxs);
  }
​
  render() {
    return (
      <div>
        <div>
          {this.state.checkBoxs.map((item, index) => (
            <div key={index}>
              <input
                type="checkbox"
                value={item.content}
                checked={item.checked}
                onChange={() => this.handleChange(index)}
              />
              <span>{item.content}</span>
            </div>
          ))}
        </div>
        <button onClick={this.clickHandle}>提交</button>
      </div>
    );
  }
}
​
export default App;

下拉列表

import React from "react";
​
class App extends React.Component {
  state = {
    value: "html"
  }
​
  handleChange = (e) => {
    this.setState({
      value: e.target.value
    });
  }
​
  clickHandle = () => {
    console.log(this.state.value);
  }
​
  render() {
    return (
      <div>
        <select value={this.state.value} onChange={this.handleChange}>
          <option value="html">HTML</option>
          <option value="css">CSS</option>
          <option value="js">JS</option>
          <option value="vue">Vue</option>
          <option value="react">React</option>
        </select>
        <button onClick={this.clickHandle}>提交</button>
      </div>
    );
  }
}
​
export default App;

非受控组件

虽然在React中推荐使用受控组件,但在某些情况下,你可能需要使用非受控组件。非受控组件允许你直接从DOM中读取值,而不是通过React的状态。

非受控组件的基本使用

import React from "react";
​
class App extends React.Component {
  constructor() {
    super();
    this.inputCon = React.createRef();
  }
​
  clickHandle = () => {
    console.log(this.inputCon.current.value);
  }
​
  render() {
    return (
      <div>
        <input type="text" ref={this.inputCon} />
        <button onClick={this.clickHandle}>获取用户输入的内容</button>
      </div>
    );
  }
}
​
export default App;

非受控组件的默认值

<div>
  {/* 一旦你用了 value,React 会认为你这是一个受控组件 */}
  {/* 如果想要给默认值,使用 defaultValue */}
  <input type="text" ref={this.inputCon} defaultValue="123" />
  <button onClick={this.clickHandle}>获取用户输入的内容</button>
</div>

文件上传

import React from "react";
​
class App extends React.Component {
  constructor() {
    super();
    this.uploadRef = React.createRef();
  }
​
  clickHandle = () => {
    console.log(this.uploadRef.current.files);
  }
​
  render() {
    return (
      <div>
        <input type="file" ref={this.uploadRef} />
        <button onClick={this.clickHandle}>获取用户输入的内容</button>
      </div>
    );
  }
}
​
export default App;

结论

受控组件和非受控组件各有其适用场景。受控组件提供了更好的数据管理和一致性,而非受控组件则在某些特定情况下更为方便。理解它们的区别和使用场景,可以帮助你更有效地处理React中的表单数据。

参考链接

关于受控组件和非受控组件的更多信息,你可以参考以下链接:Controlled vs Uncontrolled Inputs in React