How to Update CSR in React
In Client-Side Rendering (CSR) with React, updating the user interface efficiently relies on managing component state and utilizing React’s rendering lifecycle. This article explains how to trigger and handle updates in a React CSR application, focusing on state management, asynchronous data fetching, and performance optimization techniques to ensure a seamless user experience.
Triggering Updates with State and Props
In a React CSR application, the browser downloads a minimal HTML file and a JavaScript bundle that builds the DOM dynamically. To update what the user sees, you must trigger a re-render by changing either a component’s state or its props.
1. Using the useState
Hook
The most common way to update the UI is by updating local component state. When the state setter function is called, React schedules a re-render of that component and its children.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}2. Managing Complex
State with useReducer
For complex state transitions, useReducer provides a
more structured way to update the client-side state.
import { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<button onClick={() => dispatch({ type: 'increment' })}>
Count: {state.count}
</button>
);
}Updating CSR with Server Data
In CSR, initial page loads often show a loading spinner while the
application fetches data from an API. To update the view once the data
arrives, combine useEffect with state variables.
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
fetch(`https://api.example.com/users/${userId}`)
.then((res) => res.json())
.then((data) => {
setUser(data);
setLoading(false);
});
}, [userId]); // Runs again whenever userId changes
if (loading) return <p>Loading...</p>;
return <h1>{user.name}</h1>;
}Global State Updates
When multiple components across different branches of the DOM tree need to update simultaneously, local state is insufficient. You can manage global CSR updates using:
- React Context API: Ideal for low-frequency updates like UI themes or user authentication status.
- State Management Libraries: Solutions like Redux Toolkit, Zustand, or Recoil are optimized for high-frequency data updates across large applications.
Optimizing CSR Update Performance
Frequent DOM updates can cause UI lag. Implement these practices to keep your client-side updates performant:
- Use Key Props in Lists: Always provide a unique
keyprop to list items so React’s reconciliation algorithm can identify which items changed, were added, or were removed. - Memoization: Wrap expensive calculations in
useMemoand callback functions inuseCallbackto prevent unnecessary recalculations on every render. - React.memo: Prevent functional child components from re-rendering if their props have not changed.