Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React and Redux with hooks

Long time no Redux and i am getting rusty.

I remember back to the days that we had the reducer and all the app state management went through them.

Now it is really hard to understand the workflow.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So i have my store as this.

import { configureStore } from '@reduxjs/toolkit'
import userReducer from "../features/user";

export default configureStore({
  reducer: {
    user: userReducer
  },
})

And this is the so called slice?

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

export const rootSlice = createSlice({
  name: "user",
  initialState: {
    value: {
      person_in: null,
      code: null,
      surname: null,
      name: null,
      active: null,
      token: null,
      org_unit: null,
      available_days: null,
      current_available_days: null,
      total_days: null,
      is_logged_in: false,
    }
  },
  reducers: {
    updateUser: (state, action) => {
      state.value = action.payload
    }
  }
  });

 export const { updateUser } = rootSlice.actions;

 export default rootSlice.reducer;

So i get that if i want to update the state of the user i go with

dispatch(updateUser({...});

How can i update just the code attribute or any other attribute only?

>Solution :

In order to achieve the ability to update a single property of your initial state object, you need to also implement the redux concept of Action types.

You leverage the action.type value within a switch/case statement so that you can branch and update only what you need to: https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers#handling-additional-actions.

I’m not too familiar with reduxjs/toolkit but it looks like their createSlice offers this in a slightly different but very intuitive manner: https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation. Wherein you add the extraReducers function property to your createSlice object.

Here is their sample code:

import { createSlice, createAction } from '@reduxjs/toolkit'
import { createStore, combineReducers } from 'redux'

const incrementBy = createAction('incrementBy')
const decrementBy = createAction('decrementBy')

const counter = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
    multiply: {
      reducer: (state, action) => state * action.payload,
      prepare: (value) => ({ payload: value || 2 }), // fallback if the payload is a falsy value
    },
  },
  // "builder callback API", recommended for TypeScript users
  extraReducers: (builder) => {
    builder.addCase(incrementBy, (state, action) => {
      return state + action.payload
    })
    builder.addCase(decrementBy, (state, action) => {
      return state - action.payload
    })
  },
})

const user = createSlice({
  name: 'user',
  initialState: { name: '', age: 20 },
  reducers: {
    setUserName: (state, action) => {
      state.name = action.payload // mutate the state all you want with immer
    },
  },
  // "map object API"
  extraReducers: {
    [counter.actions.increment]: (
      state,
      action /* action will be inferred as "any", as the map notation does not contain type information */
    ) => {
      state.age += 1
    },
  },
})

const reducer = combineReducers({
  counter: counter.reducer,
  user: user.reducer,
})

const store = createStore(reducer)

store.dispatch(counter.actions.increment())
// -> { counter: 1, user: {name : '', age: 21} }
store.dispatch(counter.actions.increment())
// -> { counter: 2, user: {name: '', age: 22} }
store.dispatch(counter.actions.multiply(3))
// -> { counter: 6, user: {name: '', age: 22} }
store.dispatch(counter.actions.multiply())
// -> { counter: 12, user: {name: '', age: 22} }
console.log(`${counter.actions.decrement}`)
// -> "counter/decrement"
store.dispatch(user.actions.setUserName('eric'))
// -> { counter: 12, user: { name: 'eric', age: 22} }

In their example they update the counter (single property) state, and they update the user (object property) state.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading