Reputation: 11
I am using redux along with react-redux and unable to use the useSelector() function to access the updated value. My middleware shows state updating properly. I have wrapped my app in a Provider and passed in my store.
My reducers are working correctly, my middleware shows the correct updated state, and console.logs I have put inside the thunks are firing and returning the correct data, however my useSelector is returning my initial state.
Artifact Slice
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
const axios = require('axios');
const artifactSlice = createSlice({
name: 'artifactList',
initialState: {
artifacts: [],
artifactData: {},
status: 'idle',
error: null,
filter: null,
},
reducers: {
getArtifactList: (state, action) => {
state.artifactList = action.payload;
return state;
},
getArtifact: (state, action) => {
state.artifactData = action.payload;
return state;
},
setErrorMsg: (state, action) => {
state.errorMsg = action.payload;
return state;
},
extraReducers(builder) {
builder
.addCase(fetchArtifacts.pending, (state, action) => {
state.status = 'loading';
})
.addCase(fetchArtifacts.fulfilled, (state, action) => {
state.status = 'succeeded';
state.artifacts = action.payload;
})
.addCase(fetchArtifactData.pending, (state, action) => {
state.status = 'loading';
})
.addCase(fetchArtifactData.fulfilled, (state, action) => {
state.status = 'succeeded';
state.artifactData = action.payload;
})
}
}
});
export default artifactSlice.reducer;
export const {
getArtifactList,
getArtifact,
setErrorMsg,
} = artifactSlice.actions;
export const fetchArtifacts = createAsyncThunk('artifacts/fetchArtifacts', async () => {
try {
const { data } = await axios.get('http://localhost:3000/api/');
console.log("DATA: ", {data})
return data;
} catch (e) {
console.log(e);
}
});
export const fetchArtifactData = createAsyncThunk('/artifacts/fetchArtifactData', async (id) => {
try {
const { data } = await axios.get(`http://localhost:3000/api/artifacts/${id}`);
console.log("DATA: ", {data})
return data;
} catch (e) {
console.log(e);
}
})
These console logs are returning the expected values.
Create Store
import artifactReducer from './reducers/artifactSlice';
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import loggerMiddleware from "redux-logger";
export default configureStore({
reducer: {
artifact: artifactReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(loggerMiddleware),
})
Fetching Store
import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { ReactCompareSlider, ReactCompareSliderImage } from 'react-compare-slider';
import '../../css/Home.css'
import { Link } from 'react-router-dom';
import Artifact from './Artifact';
import Slider from '../slider/Slider';
import { fetchArtifacts } from '../../store/reducers/artifactSlice';
const Home = () => {
const dispatch = useDispatch();
useEffect(() => {
// const asyncFetchArtifacts = async () => {
// const fetchAllArtifacts = await dispatch(fetchArtifacts());
// }
// const artifactData = asyncFetchArtifacts();
// console.log(artifacts)
dispatch(fetchArtifacts())
},[])
const artifactData = useSelector(state => state);
console.log(artifactData)
return (rest of my html in here)
When I try to console.log(artifactData) it returns only my initial state.
EDIT: It seems like my useSelector is not running after the useEffect runs.
Upvotes: 0
Views: 759
Reputation: 225
extraReducers placement needs to be outside reducers within slice so like this:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
const artifactSlice = createSlice({
name: "artifactList",
initialState: {
artifacts: [],
artifactData: {},
status: "idle",
error: null,
filter: null,
},
reducers: {
getArtifactList: (state, action) => {
state.artifactList = action.payload;
return state;
},
getArtifact: (state, action) => {
state.artifactData = action.payload;
return state;
},
setErrorMsg: (state, action) => {
state.errorMsg = action.payload;
return state;
},
},
extraReducers(builder) {
builder
.addCase(fetchArtifacts.pending, (state, action) => {
state.status = "loading";
})
.addCase(fetchArtifacts.fulfilled, (state, action) => {
state.status = "succeeded";
state.artifacts = action.payload;
})
.addCase(fetchArtifactData.pending, (state, action) => {
state.status = "loading";
})
.addCase(fetchArtifactData.fulfilled, (state, action) => {
state.status = "succeeded";
state.artifactData = action.payload;
});
},
});
export default artifactSlice.reducer;
export const { getArtifactList, getArtifact, setErrorMsg } =
artifactSlice.actions;
export const fetchArtifacts = createAsyncThunk(
"artifacts/fetchArtifacts",
async () => {
try {
const { data } = await axios.get(
"http://localhost:3000/api/"
);
console.log("DATA: ", { data });
return data;
} catch (e) {
console.log(e);
}
}
);
export const fetchArtifactData = createAsyncThunk(
"/artifacts/fetchArtifactData",
async (id) => {
try {
const { data } = await axios.get(
`http://localhost:3000/api/artifacts/${id}`
);
console.log("DATA: ", { data });
return data;
} catch (e) {
console.log(e);
}
}
);
Upvotes: 1