You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何React重渲染后input读取defaultValue而select不读取?

点击按钮后input更新defaultValue但多选select不更新,这是预期行为吗?

这确实是React的预期行为,背后是React对表单控件初始值的处理逻辑:

核心原因

  • React中的defaultValue(以及defaultChecked)是组件首次挂载时仅生效一次的初始值,后续组件重渲染时,React不会再通过这个属性更新DOM的当前值——除非组件被卸载后重新挂载。
  • 你遇到的input“更新”是个特殊情况:初始状态下formState.description是undefined,React会将这个input标记为「未设置初始值」的状态。当后续defaultValue变为非undefined时,React会临时触发一次DOM值更新,但这并非defaultValue的常规工作逻辑,只是针对未初始化input的特殊处理。
  • 而多选select的情况:初始formState.genres是undefined,首次挂载时React会将其选中状态设为「无选项选中」。后续即使defaultValue变为['1'],由于组件已经完成挂载,React不会再根据defaultValue更新选中状态,所以select没有变化。

针对Next.js useActionState场景的解决方案

既然你需要在表单动作后保持值不重置,受控组件是更可靠的方案,完全替代defaultValue的依赖:
通过value(多选select用数组值)和onChange事件直接将控件值与状态绑定,确保状态和DOM值完全同步。

修改后的代码示例:

export default function App() {
  let [formState, setFormState] = React.useState({ genres: [], description: '' });
  return (
    <div>
      <button
          onClick={() => {
          setFormState({ genres: ['1'], description: 'New name' });
        }}
       >
          Click me
      </button>
      <div>
        <label className="block">Description:</label>
        <input
          type="text"
          name="description"
          className="border p-2 w-full"
          value={formState.description}
          onChange={(e) => setFormState(prev => ({...prev, description: e.target.value}))}
        />
      </div>

      <div>
        <label className="block">Genres:</label>
        <select
          name="genres"
          multiple
          className="border p-2 w-full"
          value={formState.genres}
          onChange={(e) => {
            const selectedValues = Array.from(e.target.selectedOptions).map(opt => opt.value);
            setFormState(prev => ({...prev, genres: selectedValues}));
          }}
        >
          <option value="1">Action</option>
          <option value="2">Comedy</option>
          <option value="3">Drama</option>
          <option value="4">Thriller</option>
          <option value="5">Sci-Fi</option>
        </select>
      </div>
    </div>
  );
}

受控组件是React表单的推荐实践,它能保证在任何状态更新时都同步DOM值,完美适配Next.js中结合useActionState的场景——动作返回的表单值可以直接更新状态,从而同步到表单控件,彻底避免依赖defaultValue的特殊行为带来的不一致问题。

内容的提问来源于stack exchange,提问作者gmoniava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:12:35