• ⑧ 表单 -- 受控组件 & 非受控组件


    1 受控组件

    • react 中,可变状态通常保存在组件的 state 属性中,并且只能通过 setState() 来更新。

    • 渲染表单的 react 组件还控制着用户输入过程中表单发生的操作。

    • 对于受控组件来说,输入的值始终由 Reactstate 驱动。

    1.1 input 标签

    class NameForm 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('提交的名字:' + this.state.value)
        event.preventDefault()
      }
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            <label>
              名字:
              <input type="text" value={ this.state.value } onChange={ this.handleChange } />
            </label>
            <input type="submit" value="提交" />
          </form>
        )
      }
    }
    

    1.2 textearea 标签

    class EssayForm 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('提交的内容:' + this.state.value)
        event.preventDefault()
      }
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            <label>
              名字:
              <textarea value={ this.state.value } onChange={ this.handleChange } />
            </label>
            <input type="submit" value="提交" />
          </form>
        )
      }
    }
    
    • this.state.value 初始化于构造函数中,因此文本区域默认有初值

    1.3 select 标签

    class FlavorForm extends React.Component {
      constructor(props) {
        super(props)
        this.state = { 
          value: 'coconut'
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
      }
      handleChange(event) {
        this.setState({
          value: event.target.value
        })
      }
      handleSubmit(event) {
        alert('你喜欢的风味:' + this.state.value)
        event.preventDefault()
      }
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            <label>
              选择你喜欢的风味:
              <select value={ this.state.value } onChange={ this.handleChange }>
              	<option value="grapefruit">葡萄</option>
              	<option value="lime">酸橙</option>
              	<option value="coconut">椰子</option>
              	<option value="mango">芒果</option>
              </select>
            </label>
            <input type="submit" value="提交" />
          </form>
        )
      }
    }
    
    注意
    • 使用 multiple={ true } 支持 select 标签多选

    1.4 处理多个输入

    • 当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作
    class Reservation extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          isGoing: true,
          numberOfGuests: 2
        }
        this.handleInputChange = this.handleInputChange.bind(this)
      }
      handleInputChange(event) {
        const { name, checked, value } = event.target
        this.setState({
          [name]: name=='isGoing' ? checked : value
        })
      }
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            <label>
              参与:
              <input name="isGoing" type="checkbox" checked={ this.state.isGoing } onChange={ this.handleInputChange } />
            </label>
            <label>
              来宾人数:
              <input name="numberOfGuests" type="number" checked={ this.state.numberOfGuests } onChange={ this.handleInputChange } />
            </label>
            <input type="submit" value="提交">
          </form>
        )
      }
    }
    

    1.5 受控组件输入空值

    • 在受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将 value 设置为 undefinednull

    指定了 value:输入最初被锁定,但在短时间延迟后变为可编辑

    2 非受控组件

    大多数情况下,推荐使用 受控组件 来处理表单数据

    • 在受控组件中,表单数据交由 react 组件来处理

    • 在非受控组件中,表单数据交由 dom 节点来处理

    • 非受控组件不是为每个状态更新都编写数据处理函数,使用 ref 来从 dom 节点中获取表单数据

    class NameForm ectends React.Component {
      constructor(props) {
        super(props)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.input = React.createRef()
      }
      handleSubmit(e) {
        alert('----', this.input.current.value)
        e.preventDefault()
      }
      render() {
        return (
          <form>
            <label> Name:
              <input type="text" ref={ this.input } />
            </label>
            <input type="submit" value="Submit" />
          </form>
        )
      }
    }
    

    2.1 默认值

    • 指定一个 defaultValue 属性
    render() {
      return (
        <form>
          <label>Name:
            <input defaultValue="Bob" type="text" ref={ this.input } />
          <label>
          <input type="submit" value="Submit" />
        </form>
      )
    }
    

    2.2 文件输入

    • react 中,<input type="file" /> 始终是一个非受控组件,因为它的值只能由用户设置不能通过代码控制
    class FileInput extends React.Component {
      constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.fileInput = React.createRef();
      }
      handleSubmit(event) {
        event.preventDefault();
        alert(
          `Selected file - ${ this.fileInput.current.files[0].name }`
        );
      }
    
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            <label>
              Upload file:
              <input type="file" ref={ this.fileInput } />
            </label>
            <br />
            <button type="submit">Submit</button>
          </form>
        );
      }
    }
    
    ReactDOM.render(
      <FileInput />,
      document.getElementById('root')
    );
    
  • 相关阅读:
    tps,qps
    JS打包与代码分割
    css module
    垃圾回收算法、内存管理
    css flex布局
    angularJS transclude
    JS模块之AMD, CMD, CommonJS、UMD和ES6模块
    js event loop事件循环
    bootstrap3之栅格系统
    viewport理解
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15411937.html
Copyright © 2020-2023  润新知