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

React父组件重渲染时子组件更新的number值丢失问题咨询

问题原因
  • 核心问题1:父组件的条件渲染逻辑错误。初始number=0时没有返回合法的渲染结果,且原有逻辑只要number<=0就会直接卸载FirstChild组件,React会在组件卸载时销毁组件内部的所有本地状态,下次组件重新挂载时useState会重新读取初始值,之前输入的内容自然会丢失。
  • 核心问题2:FirstChild内部的本地状态qtd和父组件传入的props.number没有做同步绑定。useState(props.number)只会在组件首次挂载时读取一次props值作为初始状态,后续父组件重渲染传入新的props时,本地qtd不会自动更新,很容易出现状态不一致。
  • 附加问题:输入框是受控组件但没有绑定value属性,本身就存在输入值和状态不同步的隐患。
修复方案

根据你是否需要保留「输入完成后点击按钮才同步值给父组件」的交互,选对应方案即可:

方案1:保留点击提交才同步的交互

  1. 修改父组件渲染逻辑:不要根据number值卸载FirstChild,仅控制SecondChild的条件渲染,避免输入组件被卸载导致状态销毁。
  2. 给FirstChild增加props变化同步逻辑,补全输入框的value绑定。

修正后的父组件代码

const [number, setNumber] = useState(0);

// 移除原来的if条件分支判断,始终返回合法UI
return (
  <div id='main'>
    <div>
      {/* FirstChild始终保持挂载,不被条件卸载 */}
      <Firstchild setNumber={setNumber} number={number}/>
      {/* 仅控制SecondChild在number>0时渲染 */}
      {number > 0 && <SecondChild number={number}/>}
    </div>
  </div>
);

修正后的FirstChild代码

import { useState, useEffect } from 'react';

const [qtd, setQtd] = useState(props.number);

// 监听父组件传入的number变化,同步更新本地状态
useEffect(() => {
  setQtd(props.number);
}, [props.number]);

function updateNumber(){
  // 转成数字类型再传给父组件,避免状态变成字符串
  props.setNumber(Number(qtd));
}

const handleChange = event => {
  setQtd(event.target.value);
};

return(
  <>
    {/* 补全value绑定,让输入框和本地状态实时同步 */}
    <input 
      type="number" 
      name="integerTimes" 
      className="integerTimes" 
      placeholder='Insira aqui' 
      id="qtd" 
      onChange={handleChange}
      value={qtd}
    />
    <button id="submitTimes" onClick={updateNumber}>Enviar</button>
  </>
);

方案2:不需要点击提交,实时同步值(推荐)

直接把输入状态上移到父组件维护,FirstChild不存本地状态,从根源上避免父子状态不同步、子组件卸载丢状态的问题。

修正后的FirstChild代码

function Firstchild({number, setNumber}) {
  const handleChange = event => {
    // 输入时直接同步修改父组件的状态,统一转数字类型
    setNumber(Number(event.target.value));
  };

  return(
    <>
      <input 
        type="number" 
        name="integerTimes" 
        className="integerTimes" 
        placeholder='Insira aqui' 
        id="qtd" 
        onChange={handleChange}
        value={number}
      />
      <button id="submitTimes">Enviar</button>
    </>
  );
}

父组件代码和方案1的父组件代码一致即可,状态统一存在父组件,无论怎么重渲染都不会出现值丢失的问题。

注意事项
  • 不要在函数组件的顶层条件分支里写return渲染逻辑,很容易出现某个分支无返回值、或者意外卸载组件的问题,条件渲染尽量用三元表达式或者&&运算符写在JSX内部。
  • 受控表单组件必须绑定value属性对应状态,否则会出现输入显示和状态值不一致的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:45:37