Example w/Redux
import { useDispatch, useSelector } from 'react-redux';
import { login, selectUser } from '../../store/user/userSlice';
import { useQuery } from "react-query";
import './styles.css';
const { REACT_APP_PUBLIC_API_ENDPOINT, REACT_APP_CAS_LOGIN } = process.env;
const Home = () => {
const dispatch = useDispatch();
let user = useSelector(selectUser);
console.log('render once');
const { data } = useQuery("TMP", async () => {
if (user.name) {
return;
}
const res = await fetch(`${REACT_APP_PUBLIC_API_ENDPOINT}/user`);
console.log('res: ', await res.json());
const urlParams = new URLSearchParams(window.location.search);
const ticket = urlParams.get('ticket');
const service = encodeURIComponent('http://localhost:3000/');
if (res.status === 401 && !ticket) {
// Get ticket:
window.location.href = `${REACT_APP_CAS_LOGIN}?service=${service}`;
}
else if (res.status === 401) {
// Log in:
const res = await fetch(`${REACT_APP_PUBLIC_API_ENDPOINT}/login?service=${service}&ticket=${ticket}`);
const json = await res.json();
console.log('res after logging in: ', json);
const token = json.token;
const user = await fetch(`${REACT_APP_PUBLIC_API_ENDPOINT}/user`, {
headers: {
authorization: `Bearer ${token}`
}
});
const userJson = await user.json();
console.log('res after logging in: ', userJson);
// Store in redux and localStorage:
dispatch(login(userJson));
return userJson;
}
}, { retry: false });
return (
<div>
<div>
<h2>{JSON.stringify(user)}</h2>
</div>
</div>
);
};
export default Home;
Store getting/setting localStorage:
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './user/userSlice';
const localStorageMiddleware = store => next => action => {
next(action);
localStorage.setItem('reduxState', JSON.stringify(store.getState()));
};
const preloadedState = JSON.parse(localStorage.getItem('reduxState')) || {};
export const initStore = () => configureStore({
reducer: {
user: userReducer
},
middleware: [localStorageMiddleware],
preloadedState
});
export const store = initStore();
Slice for user:
import { createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { lang: 'en' },
reducers: {
login: (state, action) => {
return { ...state, ...action.payload };
}
}
});
export const { login } = userSlice.actions;
export const selectUser = (state) => state.user;
export default userSlice.reducer;