I have this handler and function to update my react context but it's not updating. It does not dispatch the action
This function switches accounts
const loadAccountSwitch = useCallback(
async (accountId, userId, userRoleName) => {
if (!accountId || !userId || !userRoleName) return;
try {
setLoading(true);
const results = await getToken(accountId, userId, userRoleName);
const { user: apiUser,accessToken } = results.data;
setLoading(false);
if (!apiUser || typeof apiUser !== 'object' || !apiUser._id) {
console.error('Invalid apiUser:', apiUser);
return;
}
console.log('after account switch', apiUser);
console.log('isMountedRef',isMountedRef.current)
if (isMountedRef.current) {
handleClose();
dispatch({ type: 'UPDATE_USER',
payload: {
user: apiUser
}
});
}
navigate(`${PATH_DASHBOARD.general.app}`);
console.error('after navigating');
handleClose();
} catch (error) {
setLoading(false);
}
},
[dispatch, isMountedRef]
);
This function is the handler for the react context
const handlers = {
INITIALIZE: (state, action) => {
const { isAuthenticated, user } = action.payload;
return {
...state,
isAuthenticated,
isInitialized: true,
user,
};
},
LOGIN: (state, action) => {
const { user } = action.payload;
console.log('State before LOGIN:', state);
console.log('Payload in LOGIN:', user);
return {
...state,
isAuthenticated: true,
user,
};
},
UPDATE_USER: (state, action) => {
const { user } = action.payload;
return {
...state,
isAuthenticated: true,
user,
};
},
};
This is the Provider
function AuthProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
const initialize = async () => {}
initialize();
}, []);
const login = async (email, password) => {
const url = `${HOST_API}/sign`;
const response = await axios.post(url, {
email,
password,
});
if (!response || response?.data === undefined || response?.data?.code === 1) {
if (!response) {
throw new Error('Could not make request');
}
throw new Error(response.data?.message);
}
const { accessToken, user } = response.data.data;
setSession(accessToken);
dispatch({
type: 'LOGIN',
payload: {
user,
},
});
};
const contextValue = useMemo(
() => ({
...state,
method: 'jwt',
login,
}),
[state]
);
return (
<AuthContext.Provider value={contextValue}>
{children}
</AuthContext.Provider>
);
}
It runs the other codes in the account switch function but it particularly does not dispatch the action 'UPDATE_USER'
Here is a fixed version of your AuthProvider and the useReducer setup:
function AuthProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
// Example initialization function (add any logic if needed)
useEffect(() => {
const initialize = async () => {
// Any necessary initialization logic (e.g., fetching user data)
};
initialize();
}, []);
const login = async (email, password) => {
const url = `${HOST_API}/sign`;
const response = await axios.post(url, {
email,
password,
});
if (!response || response?.data === undefined || response?.data?.code === 1) {
if (!response) {
throw new Error('Could not make request');
}
throw new Error(response.data?.message);
}
const { accessToken, user } = response.data.data;
setSession(accessToken); // Ensure session is set properly
dispatch({
type: 'LOGIN',
payload: {
user,
},
});
};
const contextValue = useMemo(
() => ({
...state,
method: 'jwt',
login,
dispatch, // Make sure dispatch is provided in contextValue
}),
[state] // Dependency on state ensures context updates when state changes
);
return (
<AuthContext.Provider value={contextValue}>
{children}
</AuthContext.Provider>
);
}
export default AuthProvider;