表单

forms

  • 在 React 里,HTML 表单元素的工作方式和其他的 DOM 元素有些不同,这是因为表单元素通常会保持一些内部的 state

  • 表单具有默认的 HTML 表单行为,即在用户提交表单后浏览到新页面,如果你在 React 中执行相同的代码,它依然有效,

    但大多数情况下,使用 JavaScript 函数可以很方便的处理表单的提交,同时还可以访问用户填写的表单数据,实现这种效果的标准方式是 受控组件

受控组件

在 HTML 中,表单元素(如 input、textarea、select)之类的表单元素通常自己维护 state,并根据用户输入的进行更新,而在 React 中, 可变状态 mutable state 通常保存在组件的 state 属性中,并且只能通过使用 setState() 更新

我们可以把两者结合起来,使 React 的 state 成为 唯一数据源。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作,被 React 以这种方式控制取值的表单输入元素就叫做 受控组件

  • 设置了 value 属性,显示的值始终为 this.state.value,这使得 React 的 state 成为唯一数据源

  • 设置了 onChange 属性,使得每次按键时都会执行并更新 React 的 state,因此显示的值将随着用户输入而更新

  • input 和 select 一致

select

<select>
  <option value="grapefruit">葡萄柚</option>
  <option value="lime">酸橙</option>
  <option selected value="coconut">椰子</option>
  <option value="mango">芒果</option>
</select>
  • 由于 selected 属性的缘故,椰子选项默认被选中。React 并不会使用 selected 属性,而是在根 select 标签上使用 value 属性

  • 你可以将数组传递到 value 属性中,以支持在 select 标签中选择多个选项

  • 总的来说,这使得 input、textarea、select之类的标签都非常相似 它们都接受一个 value 属性,你可以使用它来实现受控组件

文件 input

  • 允许用户从存储设备中选择一个或多个文件,将其上传到服务器,或通过使用 JavaScript 的 File API 进行控制

  • 因为它的 value 只读,所以它是 React 中的一个 非受控 组件

处理多个输入

  • 当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作

    ```jsx harmony

class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2 };

this.handleInputChange = this.handleInputChange.bind(this);

}

handleInputChange(event) { const target = event.target; const value = target.name === 'isGoing' ? target.checked : target.value; const name = target.name;

this.setState({
  [name]: value
});

}

render() { return ( 参与: 来宾人数: ); } }

* 这里面使用了 ES6 计算属性名称的语法更新给定输入名称对应的 state 值
```javascript

// es6
this.setState({
    [name]: value
})

// es5
var partialState = {};
partialState[name] = value;
this.setState(partialState);
  • 由于 setState() 自动将部分 state 合并到当前 state,只需要调用它更改部分 state 即可

受控输入空值

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

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

受控组件的替代品

  • 有时使用受控组件会很麻烦,因为你需要为数据变化的每种方式都编写事件处理函数,并通过一个 React 组件传递所有的输入 state。

成熟的解决方案

  • Formik 是个不错的选择

最后更新于