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

React组件状态丢失:点击刷新后Input 2值被重置

React输入框组件状态丢失问题分析与解决

问题描述

我正在开发输入框组件MyInputField,采用三种不同方式渲染。点击刷新按钮后,Input 1和Input 3的值可保留,但Input 2的值每次都会被重置,刷新后第二个输入框的值为空。

代码示例

index.js

import React, { useState } from "react";
import ReactDOM from "react-dom";
import MyInputField from "./MyInputField";

import "./styles.css";

const Method3 = () => {
  return (
    <div>
      <span>Method 3</span>
      <MyInputField />
    </div>
  );
};

function App() {
  const [counter, setCounter] = useState(0);

  const method1 = () => {
    return (
      <div>
        <span>Method 1</span>
        <MyInputField />
      </div>
    );
  };

  const Method2 = () => {
    return (
      <div>
        <span>Method 2</span>
        <MyInputField />
      </div>
    );
  };

  return (
    <div className="App">
      <div>{method1()}</div>
      <Method2 />
      <Method3 />

      <button
        onClick={() => {
          setCounter(counter + 1);
        }}
      >
        Refresh me
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

MyInputField.js

import React, { useState } from "react";

const MyInputField = () => {
  const [value, setValue] = useState("");

  return (
    <input
      value={value}
      onChange={(e) => {
        setValue(e.target.value);
      }}
    />
  );
};

export default MyInputField;

原因分析

核心在于React的组件实例复用规则:React通过组件类型和在父组件中的位置判断是否复用已有组件实例。

  • Input 1对应的method1是普通函数,每次App重渲染时,它返回的JSX结构中MyInputField的位置固定,React会复用该组件实例,状态得以保留。
  • Input 3对应的Method3是定义在App外部的独立组件,组件类型稳定,React会复用Method3实例及其内部的MyInputField实例,状态保留。
  • Input 2对应的Method2是定义在App组件内部的函数组件,每次App重渲染时,这个组件定义都会被重新创建,相当于全新的组件类型。React会卸载旧的Method2实例并创建新实例,内部的MyInputField也会被重新初始化,导致状态丢失。

解决方案

将Method2的定义移到App组件外部,让它成为稳定的组件类型,避免在组件内部动态定义组件:

修改后的index.js

import React, { useState } from "react";
import ReactDOM from "react-dom";
import MyInputField from "./MyInputField";

import "./styles.css";

const Method3 = () => {
  return (
    <div>
      <span>Method 3</span>
      <MyInputField />
    </div>
  );
};

// 将Method2移到App组件外部
const Method2 = () => {
  return (
    <div>
      <span>Method 2</span>
      <MyInputField />
    </div>
  );
};

function App() {
  const [counter, setCounter] = useState(0);

  const method1 = () => {
    return (
      <div>
        <span>Method 1</span>
        <MyInputField />
      </div>
    );
  };

  return (
    <div className="App">
      <div>{method1()}</div>
      <Method2 />
      <Method3 />

      <button
        onClick={() => {
          setCounter(counter + 1);
        }}
      >
        Refresh me
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

修改后,三个输入框的状态在点击刷新按钮后都能正常保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:20:54