🌈 受控组件

const hobbiesData = [
  {
    name: '钢琴',
    value: 'piano'
  },
  {
    name: '旅行',
    value: 'travel'
  },
  {
    name: '跑步',
    value: 'running'
  },
  {
    name: '唱歌',
    value: 'singing'
  }
]
class App extends React.Component {
  state = {
    username: '',
    password: '',
    intro: '',
    gender: 'male',
    isStudent: false,
    hobbies: [],
    hobbiesData
  }
  // handleUsernameChange(e) {
  //   this.setState({
  //     username: e.target.value
  //   }, () => {
  //     console.log(this.state.username);
  //   })
  // }
  // handlePasswordChange(e) {
  //   this.setState({
  //     password: e.target.value
  //   })
  // }
  // handleIntroChange(e) {
  //   this.setState({
  //     intro: e.target.value
  //   })
  // }
  handleChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    })
  }
  handleIsStudentChange(isStudent) {
    this.setState({
      isStudent
    })
  }
  handleHobbiesChange(e) {
    if (e.target.checked) {
      this.setState({
        hobbies: [...this.state.hobbies, e.target.value]
      })
    } else {
      this.setState({
        hobbies: this.state.hobbies.filter(v => v !== e.target.value)
      })
    }
  }
  handleBtnClick(e) {
    e.preventDefault();
    const { username, password, intro, gender, isStudent, hobbies } = this.state;
    console.log(username, password, intro, gender, isStudent, hobbies);
  }
  handleResetClick(e) {
    e.preventDefault();
    this.setState({
      username: '',
      password: '',
      intro: '',
      gender: 'male',
      isStudent: false,
      hobbies: []
    })
  }
  render() {
    const { username, password, intro, gender, isStudent, hobbies, hobbiesData } = this.state;
    return (
      <form>
        <p>
          用户名:
          {/* state就是表单的唯一数据源 */}
          <input type="text" placeholder="请输入用户名"
            value={ username }
            name="username"
            onChange={ this.handleChange.bind(this) }
          />
        </p>
        <p>
          密码:
          <input type="password" placeholder="请输入密码"
            value={ password }
            name="password"
            onChange={ this.handleChange.bind(this) }
          />
        </p>
        <p>
          介绍:
          <textarea
            value={ intro }
            name="intro"
            onChange={ this.handleChange.bind(this) }
          />
        </p>
        <p>
          性别: <select
            value={ gender }
            name="gender"
            onChange={ this.handleChange.bind(this) }
          >
            <option value="male">男</option>
            <option value="female">女</option>
          </select>
        </p>
        <p>
          学生:
          <input type="radio" name="isStudent" checked={ isStudent } onChange={ this.handleIsStudentChange.bind(this, true) } />是
          <input type="radio" name="isStudent" checked={ !isStudent } onChange={ this.handleIsStudentChange.bind(this, false) } />否
        </p>
        {/* <p>
          爱好:
          <input type="checkbox" name="hobbies" value="piano" checked={ hobbies.includes('piano') } onChange={ this.handleHobbiesChange.bind(this) } />钢琴
          <input type="checkbox" name="hobbies" value="travel" checked={ hobbies.includes('travel') } onChange={ this.handleHobbiesChange.bind(this) } />旅行
          <input type="checkbox" name="hobbies" value="running" checked={ hobbies.includes('running') } onChange={ this.handleHobbiesChange.bind(this) } />跑步
          <input type="checkbox" name="hobbies" value="singing" checked={ hobbies.includes('singing') } onChange={ this.handleHobbiesChange.bind(this) } />唱歌
        </p> */}
        <p>
          爱好:
          {
            hobbiesData.map(item => {
              return (
                <span key={ item.value }>
                  <input type="checkbox" name="hobbies"
                    value={ item.value }
                    checked={ hobbies.includes(item.value) }
                    onChange={ this.handleHobbiesChange.bind(this) } />{ item.name }
                </span>
              )
            })
          }
        </p>
        <button onClick={ this.handleBtnClick.bind(this) }>Login</button>
        <button onClick={ this.handleResetClick.bind(this) }>Reset</button>
      </form>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

非受控组件

方法一

方法二(hooks)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.usernameRef = React.createRef();
    this.passwordRef = React.createRef();
    this.genderRef = React.createRef();
    this.fileRef = React.createRef();
    this.handleSubmitClick = this.handleSubmitClick.bind(this);
    this.handleResetClick = this.handleResetClick.bind(this);
  }
  handleSubmitClick(e) {
    e.preventDefault();
    // const username = this.refs.usernameRef.value;
    // const password = this.refs.passwordRef.value;
    const username = this.usernameRef.current.value;
    const password = this.passwordRef.current.value;
    const gender = this.genderRef.current.value;
    const file = this.fileRef.current.files[0];
    console.log(username, password, gender, file);
  }
  handleResetClick(e) {
    e.preventDefault();
    // this.refs.usernameRef.value = '';
    // this.refs.passwordRef.value = '';
    this.usernameRef.current.value = '';
    this.passwordRef.current.value = '';
    this.genderRef.current.value = 'male';
  }
  render() {
    return (
      <form onSubmit={ this.handleSubmitClick }>
        <p>
          用户名:
          {/* <input type="text" placeholder="请输入用户名" ref="usernameRef" /> */}
          <input type="text" placeholder="请输入用户名" ref={ this.usernameRef } />
        </p>
        <p>
          密码:
          {/* <input type="password" placeholder="请输入密码" ref="passwordRef" /> */}
          <input type="password" placeholder="请输入密码" ref={ this.passwordRef } />
        </p>
        <p>
          性别:
          <select
            // form field 的默认值 -> 组件挂载完毕后进行更新的值,不会导致DOM的任何更新
            defaultValue="male"
            ref={ this.genderRef }
          >
            <option value="male">男</option>
            <option value="female">女</option>
          </select>
        </p>
        <p>
          上传:
          <input type="file" ref={ this.fileRef } />
        </p>
        <p>
          学生:
          <input type="radio" name="isStudent" defaultChecked={ true } />是
          <input type="radio" name="isStudent" defaultChecked={ false } />否
        </p>
        <p>
          爱好:
          <input type="checkbox" name="hobbies" value="piano" defaultChecked={ true } />钢琴
          <input type="checkbox" name="hobbies" value="travel" defaultChecked={ false } />旅行
          <input type="checkbox" name="hobbies" value="running" defaultChecked={ false } />跑步
          <input type="checkbox" name="hobbies" value="singing" defaultChecked={ true } />唱歌
        </p>
        <p>
          {/* <button onClick={ this.handleSubmitClick }>登录</button> */}
          <button type="submit">登录</button>
          <button onClick={ this.handleResetClick }>重置</button>
        </p>
      </form>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));