So in my application I have a profile page which I have checked successfully sets the redux state with the profile data after dispatching when the page is loaded, I then try to access this state in another component within my app after a redirect (not a browser refresh) and using the useSelector hook but it tells me that the redux data in null and I cannot figure out why have I done something wrong in my reducers, component or store?
profileSlicer:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
export const fetchProfileByUsername = createAsyncThunk("profile/fetchByUsername", async (username) => {
console.log("fetching by username in redux ")
const response = await axios.get('http://localhost:3002/userProfile', {
params: {
username: username
}
});
return response.data;
});
export const fetchProfileByQrId = createAsyncThunk("profile/fetchByQrId", async (qr_id) => {
console.log("fetching by qr_id in redux ")
//const response = await axios.get('https://lovinglegacy.onrender.com/getProfile', {
const response = await axios.get('http://localhost:3002/getProfile', {
params: {
qr_id: qr_id
}
});
return response.data;
});
const profileSlice = createSlice({
name: 'profile',
initialState: {
isLoading: false,
data: null,
error: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchProfileByUsername.pending, (state) => {
state.isLoading = true;
})
.addCase(fetchProfileByUsername.fulfilled, (state, action) => {
state.isLoading = false;
state.data = action.payload;
})
.addCase(fetchProfileByUsername.rejected, (state) => {
state.isLoading = false;
state.error = true;
})
.addCase(fetchProfileByQrId.pending, (state) => {
state.isLoading = true;
})
.addCase(fetchProfileByQrId.fulfilled, (state, action) => {
state.isLoading = false;
state.data = action.payload;
})
.addCase(fetchProfileByQrId.rejected, (state) => {
state.isLoading = false;
state.error = true;
});
}
});
export default profileSlice.reducer;
store:
import {configureStore} from '@reduxjs/toolkit';
import profileReducer from '../redux/ProfileSlicer';
export const store = configureStore({
reducer: {
profile: profileReducer,
}
})
Component trying to access redux state in after it has been set:
import React, { useEffect } from "react";
import CreateNewMedallionProfile from "../../CreateMedallionProfile";
import { useSelector } from "react-redux";
const ProfileDetails = () => {
const profileData = useSelector(state => state.profile.data);
useEffect(() => {
console.log("Profile data in profile details ", profileData);
}, [profileData]); // Add profileData to dependency array to listen for changes
const handleClick = () => {
console.log("clicked profile data ", profileData);
}
// Render the component only if profileData exists
if (!profileData) {
return <div>Loading...</div>;
}
return (
<div>
<button onClick={handleClick}>Click</button>
<CreateNewMedallionProfile />
</div>
);
}
export default ProfileDetails;
Snippet from where redux state is set component:
const profileData = useSelector(state => state.profile.data);
const dispatch = useDispatch();
console.log("profile data from redux store = ", profileData);
useEffect(() => {
const username = localStorage.getItem('username');
const qr_id = localStorage.getItem('qr_id');
if(username) {
console.log("username from local storage ")
dispatch(fetchProfileByUsername(username));
}
else if(qr_id) {
console.log("qr_id from local storage");
dispatch(fetchProfileByQrId(qr_id));
}
// Dispatch action to fetch profile data only on page refresh
}, [])
// Effect to make GET request to sever function when profileData changes
useEffect(() => {
if(profileData) {
// Extract the username from profileData
const username = profileData.username;
console.log("in here");
// make a GET request to the server-side function
const fetchData = async () => {
try {
const response = await axios.get(`http://localhost:3002/userProfile`, {
params : {
username: username
}
});
console.log("Response from server: ", response.data);
setMedallionProfile(response.data.medallionProfile); // store fetched data in the state
// Handle the response data as needed here
} catch(error) {
console.error('Error fetching data: ', error);
// Rest of handling the error show error msg client side??
}
};
fetchData() // Call the fetchData function
}
}, [profileData]) // dependancy to run the effect when ever profile data changes