使用redux toolkit从数组中移除一个值

5

我是第一次使用 "@reduxjs/toolkit" (版本 "^1.5.1")。

我正在尝试从状态数组 (roundScore) 中删除一个对象。通常可以使用 filter() 很容易地完成此操作。但出于某种原因,这并不起作用,我无法弄清楚原因。这是我的代码:

Reducer 片段:

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
    }
]

我尝试了一些组合方式。
  • 在dispatch中使用e.target.id
  • 在dispatch中使用e.currentTarget.id
  • 在dispatch中使用({id})而不是只有(id)
  • 在reducer函数中使用或不使用括号包裹,例如在 (state, action) => { /* 代码 */ }
我错过了什么?我知道这应该是一个简单的修复,但因某种原因它一直在躲避我。
非常感谢任何帮助。

你尝试在 deleteArrow 中添加返回过滤器吗? - Viet
4个回答

26

好的,看起来问题出在filter方法的工作方式上,它会返回一个新的数组,而原始数组不会被改变(这就是为什么我们之前一直使用filter来操作redux状态),另外,在你展示的代码中,筛选操作的值没有分配给任何状态属性。你需要分配这个值或改变数组,所以下面的代码应该适用于你

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

修改您现有的数组:

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

1
谢谢。第一个建议完美地运作。对于您的第二个建议,“a”(例如“a.findIndex”)未定义。 - srWebDev
当然,你应该使用一个数组而不是一个变量a,你试图改变state.roundScore.findIndex((arrow) - Dmytro Krasnikov
1
你出现了错误。state.roundScore.splice(state.roundScore.findIndex((arrow) => arrow.id === action.payload), 1); - d-velop
5
еҪ“еүҚзҡ„жӢјжҺҘи§ЈеҶіж–№жЎҲеҸҜиғҪеӯҳеңЁжҪңеңЁзҡ„bugгҖӮеҰӮжһңз”ұдәҺжҹҗз§ҚеҺҹеӣ пјҢзҠ¶жҖҒпјҲstateпјүдёӯдёҚеҢ…еҗ«жӮЁиҰҒеҲ йҷӨзҡ„е…·жңүidзҡ„е…ғзҙ пјҢеҲҷfindIndexе°Ҷиҝ”еӣһ-1гҖӮиҝҷе°ҶеҜјиҮҙsplice(-1, 1)и°ғз”ЁпјҢ并且数组зҡ„жңҖеҗҺдёҖдёӘе…ғзҙ е°Ҷиў«еҲ йҷӨгҖӮ - Dmitriy Zhura

2
我们可以跳出局限思考,从另一种方式来看待它。上述的 React 组件实际上只是某个父组件的子组件。为了回答问题,我假设在您的父组件中有某种形式的 array.map

因此,每个数组项已经具有一个数组索引。您可以将该索引作为属性传递给上面的 React 组件,如下所示:

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
},

0

你需要改变你现有的数组

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

0
Buddy you are not returning inside state
either write 

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

or 

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

希望能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接