面试题:React 中如何为非受控组件设置默认值?

在 React 中,为非受控组件(Uncontrolled Component)设置默认值,需要使用特定的属性,而不是受控组件中使用的 value 属性。

核心方法:使用 defaultValuedefaultChecked

由于非受控组件的值由 DOM 自身管理,React 不会持续控制其 value。因此,你只能在组件首次渲染时为其设置一个初始值。React 提供了专门的属性来实现这一点:

1. defaultValue (用于 <input>, <textarea>, <select>)

  • 用于为文本输入框、文本域和下拉框设置初始值
  • 一旦组件渲染,后续的值变化由用户和 DOM 管理,React 不会再干预。
  • 如果需要动态改变这个“默认值”,非受控组件无法直接实现(这是受控组件的范畴)。
import React, { useRef } from 'react';

function NameForm() {
  const inputRef = useRef();

  const handleSubmit = (event) => {
    event.preventDefault();
    // 通过 ref 读取当前值
    console.log('名字:', inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        名字:
        {/* 使用 defaultValue 设置初始值 */}
        <input
          type="text"
          defaultValue="请输入您的名字" // ✅ 设置默认值
          ref={inputRef}
        />
      </label>
      <button type="submit">提交</button>
    </form>
  );
}

2. defaultChecked (用于 <input type="checkbox"><input type="radio">)

  • 用于为复选框和单选按钮设置初始选中状态
  • defaultValue 类似,它只在初始渲染时生效。
function PreferenceForm() {
  const checkboxRef = useRef();

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('是否接受邮件:', checkboxRef.current.checked);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        {/* 使用 defaultChecked 设置初始选中状态 */}
        <input
          type="checkbox"
          defaultChecked={true} // ✅ 初始为选中状态
          ref={checkboxRef}
        />
        接受营销邮件
      </label>
      <button type="submit">保存</button>
    </form>
  );
}

为什么不能使用 valuechecked

  • value: 如果你为非受控的 <input> 设置 value 属性,React 会认为你想要将其变为受控组件。这意味着你必须同时提供 onChange 处理器来更新 value,否则输入框将变成只读(因为 value 不会改变)。
  • checked: 同理,为复选框设置 checked 会使其变成受控组件,必须配合 onChange 使用。

与受控组件的对比

组件类型设置值的属性设置默认值的属性
受控组件value, checked❌ 不适用(value/checked 就是当前值)
非受控组件❌ 不能用 value/checked(会变受控)defaultValue, defaultChecked

总结

为非受控组件设置默认值的方法是:

  • 对于文本输入、文本域、下拉框:使用 defaultValue 属性。
  • 对于复选框和单选按钮:使用 defaultChecked 属性。

这些属性确保了元素在首次渲染时具有指定的初始值,之后的值由用户交互和 DOM 自行管理,符合非受控组件的设计理念。记住,要读取这些组件的当前值,必须使用 ref 来访问底层的 DOM 节点。

THE END
喜欢就支持一下吧
点赞13 分享