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

如何正确且优雅地将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:27:59