我有一段时间没有碰过react了,这表明我一开始就不太好。我想要一个钩子来改变状态对象的值。它会"切换">
对象中的active: bool
密钥对值。object within initial state:
hexInfo: {
name: "Hex Squadron",
active: true,
// more stuff in object
}
钩:
import React from 'react';
import SquadronIcon from './SquadronIcon';
import { useDispatch } from 'react-redux';
let SquadronsMenu = () => {
const dispatch = useDispatch();
// HEX
let seeHexInfo = () => dispatch({
type: "INFO_HEX"
});
return(
<>
{/* Hex */}
<SquadronIcon handleClick={ seeHexInfo } image={ importedImage } alt="" text="" />
)
}
export default SquadronsMenu;
reducer so far:
let reducer = (state, action) => {
switch (action.type) {
// INFO
case "INFO_HEX": return { ...state, hexInfo: { active: !active }}
default: return state;
}
};
- 当我输入
active: false
时它自然会覆盖整个对象 - 因为它是现在(与
!active
)我得到一个错误'activ' is not defined no-undef
我很容易想到有两种不同的方法来完成这个任务。
选项1:利用扩展操作符。这个选项不仅需要扩展reducer状态,还需要扩展state. hexinfo中的所有内容。
const reducer = (state, action) => {
switch (action.type) {
// INFO
case "INFO_HEX":
return {
...state,
hexInfo: {
...state.hexInfo,
active: !state.hexInfo.active,
}
}
default: return state;
}
};
选项2:如果您愿意使用其他库,请查看immer (https://immerjs.github.io/immer/docs/example-reducer)。这对于简化reducer非常有用,这样您就不必直接使用扩展操作符了。这里是immer最常见的更新模式https://immerjs.github.io/immer/docs/update-patterns的链接。
import produce from 'immer';
const initialState = {
hexInfo: {
name: "Hex Squadron",
active: true,
}
};
const reducer = (state = initialState, action) =>
produce(state, (draft) => {
switch (action.type) {
case INFO_HEX:
draft.hexInfo.active = !state.hexInfo.active;
break;
default:
}
});
export default reducer;