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

React 18子组件向父组件提升状态的实现问询

React状态提升:将UserInput组件输入同步到App组件State

需求

我需要在UserInput组件中捕获用户输入的数据,传递到App.jsx中更新并存储到对应的state里。

初始状态定义

App组件中投资数据的初始state:

const [initialInvestment, setInitialInvestment] = useState({
        initialInvestment: 100,
        annualInvestment: 200,
        expectedReturn: 3.3,
        duration: 4
    });

对应的数据结构:

{
    initialInvestment: 100,
    annualInvestment: 200,
    expectedReturn: 3.3,
    duration: 4
}

当前UserInput组件JSX代码

<div id={'user-input'}>
    <div className={'input-group'}>
        <div>
            <label>Initial Investment</label>
            <input type={'number'} defaultValue={investment.initialInvestment} onKeyDown={event => onInvestmentUpdate(event)} required/>
        </div>
        <div>
            <label>Annual Investment</label>
            <input type={'number'} defaultValue={investment.annualInvestment} onKeyDown={event => onInvestmentUpdate(event)} required/>
        </div>
        <div>
            <label>Expected Return</label>
            <input type={'number'} defaultValue={investment.expectedReturn} onKeyDown={event => onInvestmentUpdate(event)} required/>
        </div>
        <div>
            <label>Duration</label>
            <input type={'number'} defaultValue={investment.duration} onKeyDown={event => onInvestmentUpdate(event)} required/>
        </div>
    </div>
</div>

当前App组件相关代码

const investmentHandler = (investment) => {
    //const newInvestment = [...initialInvestment, ...investment];
    setInitialInvestment(prevInvestment => {
        return {
            ...prevInvestment,
            investment
        }
    });
}

<UserInput init={initialInvestment} onUpdate={investmentHandler}/>

正确实现步骤

1. 优化UserInput组件的输入绑定

  • 替换defaultValue为value,实现受控组件双向绑定
  • 给每个输入框添加name属性,对应state的键名,方便定位更新字段
  • 改用onChange事件(比onKeyDown更精准捕获输入变化)

修改后的UserInput组件JSX:

<div id={'user-input'}>
    <div className={'input-group'}>
        <div>
            <label>初始投资额</label>
            <input 
                type="number" 
                name="initialInvestment"
                value={investment.initialInvestment} 
                onChange={onInvestmentUpdate} 
                required
            />
        </div>
        <div>
            <label>年度追加投资额</label>
            <input 
                type="number" 
                name="annualInvestment"
                value={investment.annualInvestment} 
                onChange={onInvestmentUpdate} 
                required
            />
        </div>
        <div>
            <label>预期年化收益率(%)</label>
            <input 
                type="number" 
                step="0.1"
                name="expectedReturn"
                value={investment.expectedReturn} 
                onChange={onInvestmentUpdate} 
                required
            />
        </div>
        <div>
            <label>投资年限</label>
            <input 
                type="number" 
                name="duration"
                value={investment.duration} 
                onChange={onInvestmentUpdate} 
                required
            />
        </div>
    </div>
</div>

2. 实现UserInput的事件处理函数

在UserInput组件内部编写onInvestmentUpdate,将输入变化传递给父组件:

const UserInput = ({ investment, onUpdate }) => {
    const onInvestmentUpdate = (e) => {
        const { name, value } = e.target;
        // 转换输入值为对应类型
        const updatedValue = name === 'expectedReturn' ? parseFloat(value) : parseInt(value, 10);
        // 传递更新的字段到父组件
        onUpdate({ [name]: updatedValue });
    };

    return (
        // 上面修改后的JSX代码
    );
};

3. 修正App组件的更新逻辑

当前investmentHandler会错误嵌套数据,正确做法是合并更新对应字段:

const investmentHandler = (updatedField) => {
    setInitialInvestment(prevInvestment => ({
        ...prevInvestment,
        ...updatedField
    }));
};

4. 调整App组件传递给UserInput的props

将init重命名为investment,语义更清晰:

<UserInput investment={initialInvestment} onUpdate={investmentHandler} />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:56:04