I am using react-redux
with @reduxjs/toolkit
for global state management and in my store I have sliceOne
with initial state and reducer. I am trying to use the state value in a component with useSelector()
but it is showing promise instead of updated value. I dispatch action in that component.
store/sliceOne.js
import { createSlice } from "@reduxjs/toolkit";
const sliceOne = createSlice({
name: "sliceOne",
initialState: {
firstName: "first",
lastName: "last",
age: 10,
product: {},
},
reducers: {
async action1(state) {
const res = await fetch(`https://fakestoreapi.com/products/2`);
const data = await res.json();
state.product = data;
},
},
});
export const sliceOneActions = sliceOne.actions;
export default sliceOne;
component
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { sliceOneActions } from "../store/slice-one";
const Compo = () => {
const dispatch = useDispatch();
useEffect(dispatch(sliceOneActions.action1()), []); // without calling this getting state value but with this getting promise
let data = useSelector((state) => state);
console.log(data); //getting promise
return <div></div>;
};
export default Compo;
useEffect
hook by directly calling dispatch
in place of the useEffect
hook callback function.Move the asynchronous logic from the reducer function into an asynchronous action.
sliceOne
slice's extraReducers
to handled a fulfilled action1
action Promise.import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
const action1 = createAsyncThunk(
"sliceOne/action1",
async () => {
const res = await fetch("https://fakestoreapi.com/products/2");
const data = await res.json();
return data;
}
);
const sliceOne = createSlice({
name: "sliceOne",
initialState: {
firstName: "first",
lastName: "last",
age: 10,
product: {},
},
extraReducers: builder => {
builder
.addCase((action1.fulfilled, (state, action) => {
state.product = action.payload;
}));
},
});
export const sliceOneActions = {
...sliceOne.actions,
action1,
};
export default sliceOne;
Fix the UI to correctly use the useEffect
hook to dispatch the action1
action.
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { sliceOneActions } from "../store/slice-one";
const Compo = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(sliceOneActions.action1());
}), []);
const data = useSelector((state) => state);
...
};