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
相关产品推荐
相关产品推荐

