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