使用 redux 工具包从数组中删除值

Removing a value from an array using redux toolkit

我刚开始使用“@reduxjs/toolkit”(版本“^1.5.1”)。

我正在尝试从状态数组 (roundScore) 中删除一个对象。这通常是使用 filter() 非常简单的事情。出于某种原因,这不起作用,我不知道为什么。这是我的代码:

减速器切片:

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

export const roundScoreSlice = createSlice({
    name: "roundScore",
    initialState: {
        roundScore: [],
    },

    reducers: {
        deleteArrow: (state, action) => {
            console.log(`action.payload = ${action.payload}`); // returns correct id

            state.roundScore.filter((arrow) => arrow.id !== action.payload);
        },
    },
});

export const { deleteArrow } = roundScoreSlice.actions;

export default roundScoreSlice.reducer;

React 组件:

import React from "react";
import styled from "styled-components";
import { motion } from "framer-motion";
import { useDispatch } from "react-redux";
import { deleteArrow } from "../../redux-reducers/trackSession/roundScoreSlice";

export default function InputtedScore({
    arrowScore,
    id,
    initial,
    animate,
    variants,
}) {
    const dispatch = useDispatch();

    const applyStyling = () => {
        switch (arrowScore) {
            case 0:
                return "miss";
            case 1:
                return "white";
            case 2:
                return "white";
            case 3:
                return "black";
            case 4:
                return "black";
            case 5:
                return "blue";
            case 6:
                return "blue";
            case 7:
                return "red";
            case 8:
                return "red";
            case 9:
                return "gold";
            case 10:
                return "gold";
            default:
                return null;
        }
    };

    return (
        <ParentStyled
            id={id}
            initial={initial}
            animate={animate}
            variants={variants}
            onClick={() => dispatch(deleteArrow(id))}
        >
            <Circle className={applyStyling()}>
                {arrowScore}
                <IconStyled>
                    <IoIosClose />
                </IconStyled>
                <IoIosClose className="redCross" />
            </Circle>
        </ParentStyled>
    );
}

添加 2 个箭头后的状态如下所示:

roundScore: [
    {
        id:"e0f225ba-19c2-4fd4-b2bf-1e0aef6ab4e0"
        arrowScore:7
    },

    {
        id:"2218385f-b37a-4f2c-a8db-4e7e65846171"
        arrowScore:5
    }
]

我尝试了多种方法。

我错过了什么?我知道这将是一个简单的修复,但出于某种原因,我无法解决。

非常感谢任何帮助。

好的,看起来问题出在 filter 方法的工作方式上,它 returns 一个新数组,并且初始数组没有发生变化(这就是为什么我们之前一直使用 filter 来操作 redux州),同样在代码中,您已经显示未分配给您所在州的任何 属性 的过滤操作的值 您需要分配值或改变数组,因此下面的代码应该适合您

state.roundScore = state.roundScore.filter((arrow) => arrow.id !== action.payload);

改变现有数组:

state.roundScore.splice(state.roundScore.findIndex((arrow) => arrow.id === action.payload), 1);

我们可以跳出框框思考,换个角度看问题。上面的 React 组件实际上只是某个父组件的子组件。为了我的回答,我假设在你的父组件中你有某种形式的 array.map .

因此,根据该代码,每个数组项都已经有一个数组索引。你可以将该索引作为道具传递给上面的反应组件,如下所示:

const InputtedScore = ({ ...all your props, id, inputIndex }) => {
    const dispatch = useDispatch();
    // Having access to your index from the props, you can even
    // find the item corresponding to that index
    const inputAtIndex_ = useSelector(state => state.input[inputIndex])
    

    const applyStyling = () => {
        switch (arrowScore) {
            ...your style logic
        }
    };

    return (
        // you can send that index as a payload to the reducer function
        <ParentStyled id={id} onClick={() => dispatch(deleteArrow(inputIndex))} 
            ...the rest of your properties >
            <Circle className={applyStyling()}>
                {arrowScore}
                <IconStyled>
                    <IoIosClose />
                </IconStyled>
                <IoIosClose className="redCross" />
            </Circle>
        </ParentStyled>
    );
}

在通过已经将项目的索引作为有效负载发送来发送删除操作后,您不再需要在 reducer 中查找该项目:

deleteMeal: (state, action) => {
    // you receive you inputIndex from the payload
    let { inputIndex } = action.payload;
    // and you use it to splice the desired item off the array
    state.meals.splice(inputIndex, 1);
    ...your other logic if any
},