• 非受控组件
    • 默认值
  • 文件输入

    非受控组件

    在大多数情况下,我们推荐使用 受控组件 来处理表单数据。在一个受控组件中,表单数据是由 React 组件来管理的。另一种替代方案是使用非受控组件,这时表单数据将交由 DOM 节点来处理。

    要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref 来从 DOM 节点中获取表单数据。

    例如,下面的代码使用非受控组件接受一个表单的值:

    1. class NameForm extends React.Component {
    2. constructor(props) {
    3. super(props);
    4. this.handleSubmit = this.handleSubmit.bind(this);
    5. this.input = React.createRef();
    6. }
    7. handleSubmit(event) {
    8. alert('A name was submitted: ' + this.input.current.value);
    9. event.preventDefault();
    10. }
    11. render() {
    12. return (
    13. <form onSubmit={this.handleSubmit}>
    14. <label>
    15. Name:
    16. <input type="text" ref={this.input} />
    17. </label>
    18. <input type="submit" value="Submit" />
    19. </form>
    20. );
    21. }
    22. }

    在 CodePen 上尝试

    因为非受控组件将真实数据储存在 DOM 节点中,所以再使用非受控组件时,有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件。

    如果你还是不清楚在某个特殊场景中应该使用哪种组件,那么 这篇关于受控和非受控输入组件的文章 会很有帮助。

    默认值

    在 React 渲染生命周期时,表单元素上的 value 将会覆盖 DOM 节点中的值,在非受控组件中,你经常希望 React 能赋予组件一个初始值,但是不去控制后续的更新。 在这种情况下, 你可以指定一个 defaultValue 属性,而不是 value

    1. render() {
    2. return (
    3. <form onSubmit={this.handleSubmit}>
    4. <label>
    5. Name:
    6. <input
    7. defaultValue="Bob"
    8. type="text"
    9. ref={this.input} />
    10. </label>
    11. <input type="submit" value="Submit" />
    12. </form>
    13. );
    14. }

    同样,<input type="checkbox"><input type="radio"> 支持 defaultChecked<select><textarea> 支持 defaultValue

    文件输入

    在 HTML 中,<input type="file"> 可以让用户选择一个或多个文件上传到服务器,或者通过使用 File API 进行操作。

    1. <input type="file" />

    在 React 中,<input type="file" /> 始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制。

    您应该使用 File API 与文件进行交互。下面的例子显示了如何创建一个 DOM 节点的 ref 从而在提交表单时获取文件的信息。

    1. class FileInput extends React.Component {
    2. constructor(props) {
    3. super(props);
    4. this.handleSubmit = this.handleSubmit.bind(this);
    5. this.fileInput = React.createRef();
    6. }
    7. handleSubmit(event) {
    8. event.preventDefault();
    9. alert(
    10. `Selected file - ${
    11. this.fileInput.current.files[0].name
    12. }`
    13. );
    14. }
    15. render() {
    16. return (
    17. <form onSubmit={this.handleSubmit}>
    18. <label>
    19. Upload file:
    20. <input type="file" ref={this.fileInput} />
    21. </label>
    22. <br />
    23. <button type="submit">Submit</button>
    24. </form>
    25. );
    26. }
    27. }
    28. ReactDOM.render(
    29. <FileInput />,
    30. document.getElementById('root')
    31. );

    在 CodePen 上尝试