react

react-query

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;