使用 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
}
]
我尝试了多种方法。
- 在 dispatch
中使用 e.target.id
- 在 dispatch
中使用 e.currentTarget.id
- 在调度中使用 ({id}) 而不是 (id)
- 使用或不使用大括号包装 reducer 函数,例如在
(state, action) => { /* code */ }
之内
我错过了什么?我知道这将是一个简单的修复,但出于某种原因,我无法解决。
非常感谢任何帮助。
好的,看起来问题出在 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
},
我刚开始使用“@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
}
]
我尝试了多种方法。
- 在 dispatch 中使用 e.target.id
- 在 dispatch 中使用 e.currentTarget.id
- 在调度中使用 ({id}) 而不是 (id)
- 使用或不使用大括号包装 reducer 函数,例如在
(state, action) => { /* code */ }
之内
我错过了什么?我知道这将是一个简单的修复,但出于某种原因,我无法解决。
非常感谢任何帮助。
好的,看起来问题出在 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
},