如何正确且优雅地将onChange事件传递至Redux Store?
实现投注应用中比分输入的Redux状态更新
首先呀,咱们得明确核心需求:用户在Match组件的TextField里输入比分时,要实时更新Redux Store里对应赛事的home_result或away_result。下面一步步来实现:
1. 给Match组件传递赛事ID
首先得确保Matchlist容器在传递props给Match组件时,把赛事的id也传过去——毕竟咱们要精准定位到要更新的那场比赛对吧?
// Matchlist组件里渲染Match的部分 {this.props.matches.map(match => ( <Match key={match.id} game={match} matchId={match.id} // 新增传递matchId,用于定位赛事 /> ))}
2. 编写Redux Action
接下来创建一个action,用来告诉Reducer:“我要更新某场比赛的某个比分啦”:
// actions/matchActions.js export const updateMatchScore = (matchId, scoreType, value) => ({ type: 'UPDATE_MATCH_SCORE', payload: { matchId, scoreType, // 可选值:'home_result' 或 'away_result',标记要更新的是主场还是客场比分 value: parseInt(value) || 0 // 转成数字,默认0防止非数字输入导致的异常 } });
3. 在Reducer中处理更新逻辑
然后在对应的Reducer里,处理UPDATE_MATCH_SCORE这个action——记住Redux要求状态不可变,所以咱们要返回新的数组,不能直接修改原数组:
// reducers/matchReducer.js const initialState = { matches: [] // 你的初始赛事数组 }; const matchReducer = (state = initialState, action) => { switch(action.type) { case 'UPDATE_MATCH_SCORE': const { matchId, scoreType, value } = action.payload; // 遍历赛事数组,找到对应id的赛事并更新指定比分 const updatedMatches = state.matches.map(match => { if (match.id === matchId) { return { ...match, // 拷贝原赛事的其他属性 [scoreType]: value // 动态更新对应的比分字段 }; } return match; // 其他赛事保持不变 }); return { ...state, matches: updatedMatches }; default: return state; } }; export default matchReducer;
4. 在Match组件中实现onChange Handler
现在回到Match组件,需要把Redux的dispatch方法绑定进来,然后实现对应的输入处理函数:
类组件版本:
import { connect } from 'react-redux'; import { updateMatchScore } from '../actions/matchActions'; class Match extends React.Component { homeScoreChangedHandler = (e) => { // 触发action,更新当前赛事的主场比分 this.props.updateMatchScore( this.props.matchId, 'home_result', e.target.value ); }; awayScoreChangedHandler = (e) => { // 同理实现客场比分的更新逻辑 this.props.updateMatchScore( this.props.matchId, 'away_result', e.target.value ); }; render() { return ( <div> <TextField value={this.props.game.home_result} onChange={this.homeScoreChangedHandler} type="number" // 限制输入为数字,提升用户体验 /> <TextField value={this.props.game.away_result} onChange={this.awayScoreChangedHandler} type="number" /> </div> ); } } // 把action绑定到组件props上 export default connect(null, { updateMatchScore })(Match);
函数组件版本(用React-Redux Hooks):
import { useDispatch } from 'react-redux'; import { updateMatchScore } from '../actions/matchActions'; const Match = ({ game, matchId }) => { const dispatch = useDispatch(); const homeScoreChangedHandler = (e) => { dispatch(updateMatchScore(matchId, 'home_result', e.target.value)); }; const awayScoreChangedHandler = (e) => { dispatch(updateMatchScore(matchId, 'away_result', e.target.value)); }; return ( <div> <TextField value={game.home_result} onChange={homeScoreChangedHandler} type="number" /> <TextField value={game.away_result} onChange={awayScoreChangedHandler} type="number" /> </div> ); }; export default Match;
这样一来,每当用户在TextField里输入比分时,对应的onChange处理函数就会触发Redux action,Reducer更新Store里的赛事数据,Matchlist会重新获取更新后的matches数组并传递给Match组件,TextField的value就会实时同步最新的比分啦!
内容的提问来源于stack exchange,提问作者Fernando Maymone
相关产品推荐
相关产品推荐

