受控和非受控组件

54 阅读2分钟

受控组件 ★★★

  • React 的 state 作为“唯一数据源”。
  • 渲染表单元素的 React 组件控制着用户输入过程中表单发生的操作。
  • 被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
import React, { PureComponent } from 'react'

export class App extends PureComponent {
  constructor() {
    super()
    this.state = {
      value: "我是受控组件"
    }
  }
  handleChange(event) {
    this.setState({ value: event.target.value });
  }
  render() {
    const { value } = this.state
    return (
      <div>
        {/* 受控组件 */}
        <input type="text" value={value} onChange={e => this.handleChange(e)} />
        {/* 非受控组件 */}
        <input type="text" />
        <h1>{value}</h1>
      </div>
    )
  }
}

export default App

对于受控组件来说,输入的值始终由 React 的 state 驱动。你也可以将 value 传递给其他 UI 元素,或者通过其他事件处理函数重置

非受控组件★★★

  • 在一个受控组件中,表单数据是由 React 组件来管理的。
  • 另一种替代方案是使用非受控组件,这时表单数据将交由 DOM 节点来处理。
  • 赋予组件一个初始值:指定一个 defaultValue 属性,而不是 value。在一个组件已经挂载之后去更新 defaultValue 属性的值,不会造成 DOM 上值的任何更新。
import React, { PureComponent, createRef } from 'react'

export class App extends PureComponent {
  constructor() {
    super()
    this.state = {
      value: "我是受控组件"
    }
    this.input = createRef();
  }
  handleChange() {
    // console.log(this.input.current.value);
    this.setState({ value: this.input.current.value });
  }
  render() {
    const { value } = this.state
    return (
      <div>
        {/* 非受控组件 */}
        <input type="text" defaultValue="我是默认值" ref={this.input} onChange={e=>this.handleChange()}/>
        <h1>{value}</h1>
      </div>
    )
  }
}

export default App

受控组件多个输入处理

import React, { PureComponent } from 'react'

export class App extends PureComponent {
  constructor() {
    super();
    this.state = { name: "", age: "", };
  }

  handleChange(event) {
    const name = event.target.name;
    //ES6 计算属性名称的语法更新给定输入名称对应的 state 值:
    this.setState({ [name]: event.target.value });
  }

  handleSubmit(event) {
    console.log(this.state);
    event.preventDefault();
  }
  render() {
    const { name, age } = this.state
    return (
      <div>
        <form onSubmit={e => this.handleSubmit(e)}>
          <label htmlFor='name'>
            名字:
            <input type="text" id='name' name="name" value={name} onChange={el => this.handleChange(el)} />
          </label>
          <label htmlFor='age'>
            年龄:
            <input type="number" id='age' name="age" value={age} onChange={el => this.handleChange(el)} />
          </label>
          <input type="submit" value="提交" />
        </form>
      </div>
    )
  }
}

export default App

checkbox

//···
handleChange(event) {
    const name = event.target.name;
    this.setState({ [name]: event.target.checked });
  }
  render() {
    const { bool } = this.state
    return (
      <div>
        <form onSubmit={e => this.handleSubmit(e)}>
          <label htmlFor='bool'>
            <input type="checkbox" id='bool' name='bool'  checked={bool} onChange={el => this.handleChange(el)} />协议
          </label>
          
          <input type="submit" value="提交" />
        </form>
      </div>
    )
  }
  //···

数组用法

import React, { PureComponent } from 'react'
export class App extends PureComponent {
  constructor() {
    super();
    this.state = {
      arrrayList: [
        { name: "林夕", value: "linxi", check: false },
        { name: "林夕1", value: "linxi1", check: false },
        { name: "林夕2", value: "linxi3", check: false }
      ]
    };
  }
  handleSubmit(event) {
    console.log(this.state);
    const names = this.state.arrrayList.filter((item) => item.check).map(item=>item.name)
    console.log(names);
    event.preventDefault();
  }

  handleChange(event, index) {
    const arrrayList = [...this.state.arrrayList]
    arrrayList[index].check = event.target.checked
    this.setState({ arrrayList })
  }
  render() {
    const { arrrayList } = this.state
    return (
      <div>
        <form onSubmit={e => this.handleSubmit(e)}>

          {
            arrrayList.map((item, index) => {
              return (
                <label htmlFor={item.value} key={item.value}>
                  <input type="checkbox" id={item.value} checked={item.check} onChange={el => this.handleChange(el, index)} />{item.name}
                </label>
              )
            })
          }
          <input type="submit" value="提交" />
        </form>
      </div>
    )
  }
}
export default App