Home > front end >  how to override state Redux
how to override state Redux

Time:11-14

I don't understand something in react-redux. I have created a slice called Introduction look below:

import { createSlice } from "@reduxjs/toolkit";
import { IntroductionFields } from "../helpers/interface";


const initialState: IntroductionFields = {
  fullName:'',
  subtitle:'',
  description:'',
  location:'',
  email:'',
  portfolio: {name:'' , url:''},
  project: {name: '' , url: ''},
  learning: '',
  collaborating: '',
  else: '',
}

const Introduction = createSlice({
  name: 'intro',
  initialState,
  reducers:{
    update(state, actions){
      const key = actions.payload.name;
      const val = actions.payload.value;
      state.fullName = val; // WORK 
      state = {...state, [key]: val} // NO WORK
      console.log(actions.payload.name , " " , actions.payload.value);
    },

  }
})

export const IntroductionActions = Introduction.actions;
export default Introduction;

and I have two more components, first component has fields (inputs) and every field has an onChange that calls the dispatch and uses update on the reducer that I created in the introduction slice and I send the key and value, see below.

const Intro: React.FC<Props> = ({ moveForward }) => {
  const dispatch = useDispatch();
  const changeHandler = (event: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => {
    const {name , value} = event.target;
    dispatch(IntroductionActions.update({name, value}))
  }

    return (.... // HERE I HAVE INPUTS...)

}

In the second component I want to get the values from the Introduction slice so if I change some fields in Intro component, I want to see the changes in my Preview component.

import React, { useEffect } from 'react'
import classes from './Preview.module.scss';
import { useSelector } from 'react-redux';
import { RootState } from '../../../store/store';

const Preview = () => {
  const introduction = useSelector((state:RootState) => state.intro);
  
  return (
    <div className={classes.previewContainer}>
      {introduction.fullName && <h1>Hi! My name is {introduction.fullName}</h1>}
    </div>
  )
}

export default Preview

If you'll look to the first code section you will see these two lines.

  state.fullName = val; // WORK 
  state = {...state, [key]: val} // NO WORK

If I directly write into the field in state it works prefect, but if I try to do the second line it doesn't work... I want it to be dynamic that is why I want to use the second line...

CodePudding user response:

Dispatch the action with object as payload

dispatch(IntroductionActions.update({fullName: name, subtitle: subtitle}))

and your reducer function will be like this

    update(state, actions){
      return ({...state, ...actions.payload})
}

Here based on the payload, state will get updated , here fullName and subtitle values will get updated.

CodePudding user response:

You can set the state like this since there is no need to copy the whole state to the new state.

update(state, actions){
  const key = actions.payload.name;
  const val = actions.payload.value;
  state[key] = val;
},

The section Create a Redux State Slice will explain in depth how/why

  • Related