React 受控组件和非受控组件

129 阅读2分钟

受控组件

  • React控制的组件

  • input等表单输入框值不存在于 DOM 中,以组件状态存在

  • 通过props获取其当前值,通过回调函数(比如onChange)通知变化

  • 组件渲染出的状态与它的valuechecked属性相对应

  • 表单状态发生变化时,更新值时调用setState

  • 会更新state的流程

export default function App() {
    const [name, setName] = useState('');
  
    const handleNameChange = e => {
      setName(e.target.value);
    }
  
    return (
      <div className="App">
        <div>hello {name}</div>
        姓名:<Input onChange={handleNameChange} />
      </div>
    );
  }

受控组件-示例代码

  • 代码中有一个输入框,界面展示了输入框的内容,随着输入框内容的变化,上方文字相应变化

  • 表单组件Input的值通过onChange回调交给React处理

  • React获取到表单的值(e.target.value)之后,将其保存到了状态变量name

  • 界面展示内容通过读取组件状态name,因此name的变化触发<div>hello {name}</div>的重新渲染

非受控组件

  • 存储在DOM中,而不是 React 组件内,类似于传统的HTML表单元素

  • 值不受组件自身的stateprops控制

  • refDOM中获取元素数据

export default function App() {
    const eleRef = useRef(null);
    const [submitContent, setSubmitContent] = useState("");
  
    const handleSubmit = () => {
      // 通过ref获取输入框的值
      const content = eleRef.current?.value;
      setSubmitContent(content);
    };
  
    return (
      <div className="App">
        <input ref={eleRef} />
        <Button type="primary" onClick={handleSubmit}>
          提交
        </Button>
        <div>{submitContent ?? ""}</div>
      </div>
    );
  }

非受控组件-示例代码

  • 页面中包含一个输入框、一个按钮,通过ref获取到输入框的引用,在改变输入内容之后,点击提交,页面会展示输入框内容

  • React通过ref获取input元素的值

  • input值由用户改变,点击提交按钮,在handleSubmit中通过ref获取DOM元素,进而读取输入框的值

  • 输入框的变化并未交由组件控制,而是通过ref获取,也就是直接在DOM中读取

总结

  1. React中的组件分为受控组件和非受控组件

  2. 受控组件的两个要点

    • 组件的value属性与React中的状态绑定

    • 组件内声明了onChange事件处理value的变化

  3. 非受控组件更像是传统的HTML表单元素,数据存储在DOM中,而不是组件内部,获取数据的方式是通过ref引用

建议

  • 尽可能使用受控组件

  • 受控组件是将状态交由React处理,可以是任何元素,不局限于表单元素

  • 大量表单元素的页面:用非受控组件

  • 在受控组件中,数据流是单向的(state是变化来源),用setState改变state

  • Refs不能用于函数式组件,因为函数式组件没有实例

  • 在函数式组件内部,是可以使用Refs

链接:juejin.cn/post/702098…