Reputation: 60
I haven't touched react in a while and it shows, not that I was very good to begin with. I'd like a Hook to change a value of an object in state. It would "toggle" an active: bool
key-pair value in the object.
object inside initial state:
hexInfo: {
name: "Hex Squadron",
active: true,
// more stuff in object
}
Hook:
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
it naturally overwrites the entire object!active
) I get an error 'activ' is not defined no-undef
Upvotes: 0
Views: 1381
Reputation: 491
There are two different ways that I can easily think to accomplish this.
Option 1: Utilize the spread operator. This option requires you to not only spread the reducer state but also everything within 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;
}
};
Option 2: If you are willing to use an additional library, check out immer (https://immerjs.github.io/immer/docs/example-reducer). It is great for simplifying reducers so that you do not have to use the spread operator directly. Here is a link to the most common update patterns with 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;
Upvotes: 3