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

