什么是 React 受控组件和非受控组件?

What are React controlled components and uncontrolled components?

ReactJS 中的受控组件和非受控组件是什么?他们有什么不同?

这与有状态 DOM 组件(表单元素)有关,React 文档解释了差异:

  • Controlled Component 是一种通过 props 获取当前值并通过 onChange 等回调通知更改的方法。父组件 "controls" 它通过处理回调和管理自己的状态并将新值作为道具传递给受控组件。您也可以称其为 "dumb component"。
  • A Uncontrolled Component 是一个在内部存储自己状态的,当你需要它时,你可以使用 ref 查询 DOM 来找到它的当前值。这有点像传统的 HTML.

大多数本机 React 表单组件都支持受控和非受控使用:

// Controlled:
<input type="text" value={value} onChange={handleChange} />

// Uncontrolled:
<input type="text" defaultValue="foo" ref={inputRef} />
// Use `inputRef.current.value` to read the current value of <input>

在大多数(或所有)情况下you should use controlled components

受控组件是从回调函数中获取更改值的组件 和 不受控制的组件是具有 DOM 中的组件的组件。 例如, 当输入值改变时,我们可以在受控组件中使用 onChange 函数和 我们也可以使用 DOM 来获取值,比如 ref.

受控组件主要是那些组件的任何 prop 值来自父组件或来自商店的组件(如 redux 的情况)。示例:

<ControlledComp value={this.props.fromParent}/>

在不受控制的组件的情况下,可以根据事件处理从组件的状态中获取组件值。示例:

<UncontrolledComp value={this.state.independentValue}/>

它们都呈现表单元素

不受控组件受控组件是用来描述呈现HTML表单的React组件的术语元素。每次您创建一个呈现 HTML 表单元素的 React 组件时,您都在创建这两个元素之一。

非受控组件受控组件的不同之处在于它们从表单元素[=53]访问数据的方式不同=] (<input>, <textarea>, <select>).

不受控制的组件

一个uncontrolled component is a component that renders form elements, where the form element's data is handled by the DOM (default DOM behavior). To access the input's DOM node and extract its value you can use a ref.

示例 - 不受控制的组件:
const { useRef } from 'react';

function Example () {
  const inputRef = useRef(null);
  return <input type="text" defaultValue="bar" ref={inputRef} />
}

受控组件

controlled component 是一个呈现表单元素并通过将表单数据保持在组件状态中来控制它们的组件。

受控组件中,表单元素的数据由 React 组件处理(不是 DOM)并保持组件状态。受控组件基本上会覆盖 HTML 表单元素的默认行为。

我们通过将表单元素(<input><textarea><select>)连接到 state 通过设置其属性 value 和事件 onChange.

示例 - 受控组件:
const { useState } from 'react';

function Controlled () {
  const [email, setEmail] = useState();

  const handleInput = (e) => setEmail(e.target.value);


  return <input type="text" value={email} onChange={handleInput} />;
}

受控组件不保持其状态。

他们需要的数据从父组件传递给他们。

他们通过回调函数与此数据交互,回调函数也从父级传递给子级。