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

React Redux中如何将过滤后的对象推入空数组?(含业务场景)

在React Redux中实现点击列表项将对应对象加入selectedPersons数组

嘿,我来帮你梳理下怎么实现这个需求~ 咱们得紧扣React Redux的核心逻辑:所有状态更新都要通过 dispatch action 触发,reducer 根据 action 类型来处理状态变更。结合你的场景,一步步来:


1. 定义Action类型和Action Creator

首先得创建一个用于添加选中人员的action标识,以及对应的action创建函数,用来传递选中的人员对象:

// 定义action类型(建议用大写常量,避免拼写错误)
export const ADD_SELECTED_PERSON = 'ADD_SELECTED_PERSON';

// Action Creator:接收选中的person对象作为参数,返回标准action格式
export const addSelectedPerson = (person) => ({
  type: ADD_SELECTED_PERSON,
  payload: person
});

2. 编写Reducer处理状态更新

接下来要在reducer里处理这个action,把选中的person添加到selectedPersons数组里。这里要注意一个实用细节:避免重复添加同一个人员,先判断该person的id是否已经在选中列表里存在:

import { ADD_SELECTED_PERSON } from './actions';

// 初始状态对应你给出的结构
const initialState = {
  items: [],
  selectedPersons: []
};

const personReducer = (state = initialState, action) => {
  switch (action.type) {
    // 处理你componentDidMount里获取人员列表的逻辑
    case 'FETCH_PERSONS_SUCCESS': // 假设你用这个action类型存接口返回的数据
      return {
        ...state,
        items: action.payload
      };
    
    // 处理添加选中人员的逻辑
    case ADD_SELECTED_PERSON:
      // 检查当前人员是否已经被选中
      const isAlreadySelected = state.selectedPersons.some(
        person => person.id === action.payload.id
      );
      if (isAlreadySelected) {
        // 已存在则直接返回原state,不做更新
        return state;
      }
      // 不存在则返回新状态,把选中人员追加到数组
      return {
        ...state,
        selectedPersons: [...state.selectedPersons, action.payload]
      };
    
    default:
      return state;
  }
};

export default personReducer;

3. 在组件中处理点击事件并Dispatch Action

现在回到你的组件,点击列表项时,先从state.items里找到对应id的person对象,再dispatch咱们定义的action:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addSelectedPerson } from './actions';

class PersonList extends Component {
  componentDidMount() {
    // 这里是你原来的fetchPersons逻辑,获取数据后dispatch存到state里
    fetch('/api/persons')
      .then(res => res.json())
      .then(data => {
        this.props.dispatch({
          type: 'FETCH_PERSONS_SUCCESS',
          payload: data
        });
      });
  }

  selectedPerson = (id) => {
    // 根据id从items数组中找到对应的person对象
    const targetPerson = this.props.items.find(person => person.id === id);
    if (targetPerson) {
      // 触发action添加到选中列表
      this.props.dispatch(addSelectedPerson(targetPerson));
    }
  };

  render() {
    return (
      <div>
        {this.props.items.map(person => (
          <div 
            key={person.id}
            onClick={() => this.selectedPerson(person.id)}
            style={{ cursor: 'pointer', padding: '8px', margin: '4px 0', border: '1px solid #eee' }}
          >
            {person.name}
          </div>
        ))}
      </div>
    );
  }
}

// 把Redux中的状态映射到组件的props
const mapStateToProps = (state) => ({
  items: state.personReducer.items,
  selectedPersons: state.personReducer.selectedPersons
});

// 用connect连接组件和Redux
export default connect(mapStateToProps)(PersonList);

额外优化:用Redux Toolkit简化代码

如果你用的是现在更推荐的Redux Toolkit,代码能简化不少,它会自动处理不可变更新,还能一键生成action和reducer:

import { createSlice } from '@reduxjs/toolkit';

const personSlice = createSlice({
  name: 'persons',
  initialState: {
    items: [],
    selectedPersons: []
  },
  reducers: {
    fetchPersonsSuccess: (state, action) => {
      state.items = action.payload;
    },
    addSelectedPerson: (state, action) => {
      const isExist = state.selectedPersons.some(p => p.id === action.payload.id);
      if (!isExist) {
        state.selectedPersons.push(action.payload);
      }
    }
  }
});

export const { fetchPersonsSuccess, addSelectedPerson } = personSlice.actions;
export default personSlice.reducer;

用这种方式的话,组件里的dispatch逻辑和之前基本一致,直接导入slice导出的action就行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:00:15