Careeroza
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?
- Keep auth state (user, token) in an AuthContext (or Redux).
- Use one API client (axios instance / fetch wrapper) for all requests.
- Add a response interceptor: on
401, try a refresh token once; if that fails, clear auth and redirect to/login. - Wrap private pages in a ProtectedRoute that redirects when there is no user.
- 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);
}
);