I will try to update an object in reducer, once state is updated in reducer then i set the value using useState in functional component. But first time its working when i try to updated second time its not updated, showing only previous value. ReactNative
**Component**
const Catpoint = () => {
const { cPoint} = useSelector((state) => state.ckpoint)
const [ckpt, setCKPT] = useState(cPoint)
useEffect(()=>{
setCKPT(cPoint)
},[cPoint])
const updatecPoint = () => {
ckpt.options =[{user:"suresh", status:"0"}, {user:"alex", status:"1" ]
dispatch(updateCKPT(ckpt)
}
}
return <View>
<TouchableOpacity onPress={()=> updatecPoint() }> Update User Status </TouchableOpacity>
</View>
export default Catpoint
**Reducer**
const initialcpoinState = {
cPoint:{
pointName:"test",
options:[{user:"suresh", status:"0"}, {user:"alex", status:"0" ]
}
}
const cpointSlice = createSlice({
name: "cpointData",
initialState: initialcpoinState,
reducers: {
updateCheckpointInfo:(state, action) => {
Object.assign(state.cPoint, {...action.payload})
}
})
export const {
updateCheckpointInfo
} = cpointSlice.actions
export default cpointSlice
CodePudding user response:
This is a classic case of mutating state. The mutation occurs in this line:
ckpt.options = [{user:"suresh", status:"0"}, {user:"alex", status:"1"}]
You cannot mutate the ckpt
object because it is a React state. In this case you're actually messing up your Redux state too. The initial value of the ckpt
state comes from your useSelector
hook so it is the same object instance in both places. Mutating one will change the other.
There is no need to have a local component state at all. Just dispatch
the changes which you want to apply to the checkpoint and the cPoint
variable from the useSelector
hook will update automatically.
Your reducer is already merging the action.payload
with the existing state.cPoint
so you do not need to pass a complete checkpoint object in your action. You can simply pass the fields which you want to change.
const Catpoint = () => {
const { cPoint } = useSelector((state) => state.ckpoint);
const updatecPoint = () => {
dispatch(
updateCKPT({
options: [{ user: "suresh", status: "0" }, { user: "alex", status: "1" }]
})
);
};
return (
<View>
<TouchableOpacity onPress={() => updatecPoint()}>
Update User Status
</TouchableOpacity>
</View>
);
};
export default Catpoint;