【Day10】表单 Form:受控元件 Controlled Component

在 React 中,允许直接用 HTML 来建立表单,
但使用 JavaScript function
处理提交表单、读取使用者在表单中填入的资料
更加常见也更方便。

要做到这点,
标准的方法是使用「受控元件


受控元件 Controlled Component

在 React 中,一般会使用
可变的 state 作为表单元素的值,
并以 setState() 作为唯一更新方式,
藉此掌握後续使用者输入对表单带来的改变,
表单元素(<input><textarea><select>
显示的 value 始终由 React 的 state 驱动,
成为它们「唯一真相来源」。

像这样被 React 控制值的元件,
就被称为「受控元件(Controlled Component)」。

react 表单范例

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };

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

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

  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Essay:
          <textarea value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

资料处理步骤

  1. 由初始 state 设定表单初始值
  2. 每当栏位值发生变化都会呼叫 onChange 事件
  3. 事件处理透过 event 拿到改变的状态更新 state
  4. setState 触发重新绘制,完成表单元件值的更新

select 标签

将一个 array 传给 value 这个属性
select 标签就可以使用多重选项

<select multiple={true} value={['B', 'C']}>

处理多个输入

一次需要处理多个
controlled input element 时,
可以利用 name attribute,
让 handler function 依照
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 target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({[name]: value});
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

补充:动态计算属性名(computed property name)

使用 ES6 的动态计算属性名方法

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

和以下的 ES5 程序码是一样的:

var partialState = {};
partialState[name] = value;
this.setState(partialState);

由於 setState() 会自动 merge state,
只需要在有改变的地方呼叫它即可


<<:  (Day26) 使用 fetch 串接 Ajax

>>:  Day14 - 使用表单新增资料

Day 14:vim-plug

前面讲过了 zsh、tmux 的 plugin manager,vim 一样有 plguin man...

30天零负担轻松学会制作APP介面及设计【DAY 17】

大家好,我是YIYI,今天我要来制作记帐和报表的页面。 记帐页面 和制作前面的页面一样,先将BACK...

[Day30] 建立购物车系统 - 13 & 完赛心得

1. 修改docker-compose.yml 将购物车与其他系统都改成docker执行,修改doc...

第二十八天:用 TeamCity 发布 Package

在这系列教学里,我们以撰写一个以购物车为主题的 Kotlin 函式库为例,经过一连串 TDD、语法风...

[机派X] Day 8 - 我是 Bash 我调皮,令人匪夷所思的 Bash 语法

引言 昨天介绍了套件管理软件以及图形化使用者界面的安装,也是指令介绍的最後一篇文章。学习了这麽多指令...