受控组件与非受控组件

263 阅读2分钟

受控组件

在HTML中,表单元素的标签<input><textarea><select>等的值改变通常是根据用户输入进行更新。
在React里,可变状态通常保存在组件的state属性中,并且只能通过setState()来进行更新。渲染表单的React组件控制着用户输入过程中表单发生的操作,被React以这种方式控制取值的表单输入元素就叫做受控组件
来个例子:

import { useState } from "react";
import "./styles.css";

export default function App() {
const [notes, setNotes] = useState("notes");

console.log(notes);

return (
<div className="App">
请输入值:
<input value={notes} />
</div>
);
}

当我们在输入框输入内容的时候,会发现输入的内容无法显示出来,input标签只是只读状态。这时候,我们可以添加onChange事件,如下:

import { useState } from "react";
import "./styles.css";

export default function App() {
const [notes, setNotes] = useState("notes");

console.log(notes);

const onChange = (e) => {
setNotes(e.target.value);
};
return (
<div className="App">
请输入值:
<input value={notes} onChange={onChange} />
</div>
);
}

这时候发现输入框可以输入内容,并且控制台也能实时的打印输入的内容。在我们输入的时候会触发onChange事件函数,在函数内部实现state的更新,从而导致input框的内容发生改变。

非受控组件

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

将上述例子改写为非受控组件:

import { useState, useRef } from "react";
import "./styles.css";

export default function App() {
const [notes, setNotes] = useState("");

console.log(notes);

const refInput = useRef(null);
const onBlur = () => {
setNotes(refInput.current.value);
};

return (
<div className="App">
请输入值:
<input ref={refInput} defaultValue={notes} onBlur={onBlur} />
</div>
);
}

input框可以输入内容,并且失去焦点时会触发相应的函数,通过defaultValue设置默认值。

总结

<Input value={x} onChange={fn}> // 受控组件
<Input defaultValue={x} ref={input}/> //非受控组件
  • 受控组件的状态由开发者维护
  • 非受控组件的状态由组件自身维护

参考链接
react.docschina.org/docs/forms.…
www.jianshu.com/p/04dfbf76d…
www.cnblogs.com/houxianzhou…