State and Architecture Scenarios

A dashboard has charts and tables that share filters (date range, category). How do you manage the state?

For a small–medium app: put the filters in a FilterContext managed with useReducer, so any chart reads them without props drilling. If filters affect many parts of a large app, or I need DevTools/middleware/caching, I use Redux Toolkit with selectors. UI-only state (pagination inside one table, loading flags) stays local. Charts are wrapped in React.memo and their derived data in useMemo so unrelated changes do not re-render them.

Example

import { createContext, useContext, useReducer, memo } from 'react';

const FilterContext = createContext(null);
function filterReducer(state, action) {
  return { ...state, [action.field]: action.value };
}

function Filters() {
  const { filters, dispatch } = useContext(FilterContext);
  return (
    <select value={filters.category} onChange={(e) => dispatch({ field: 'category', value: e.target.value })}>
      <option>All</option><option>Books</option><option>Toys</option>
    </select>
  );
}
const Chart = memo(function Chart() {
  const { filters } = useContext(FilterContext);
  return <p>📊 Sales chart for: {filters.category}</p>;
});
const Table = memo(function Table() {
  const { filters } = useContext(FilterContext);
  return <p>📋 Orders table for: {filters.category}</p>;
});

export default function App() {
  const [filters, dispatch] = useReducer(filterReducer, { category: 'All' });
  return (
    <FilterContext.Provider value={{ filters, dispatch }}>
      <Filters /><Chart /><Table />
    </FilterContext.Provider>
  );
}

Result

A user logs in and sees a dashboard. If the token expires, they must be redirected to login. How do you handle this globally?

  1. Keep auth state (user, token) in an AuthContext (or Redux).
  2. Use one API client (axios instance / fetch wrapper) for all requests.
  3. Add a response interceptor: on 401, try a refresh token once; if that fails, clear auth and redirect to /login.
  4. Wrap private pages in a ProtectedRoute that redirects when there is no user.
  5. Optionally check the token expiry time on load and set a timer to log out.
// api.js
const api = axios.create({ baseURL: '/api' });

api.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) config.headers.Authorization = 'Bearer ' + token;
  return config;
});

api.interceptors.response.use(
  (res) => res,
  (error) => {
    if (error.response?.status === 401) {
      localStorage.removeItem('token');
      window.location.href = '/login?expired=1';   // or call logout() + navigate from context
    }
    return Promise.reject(error);
  }
);