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:

Optimizing CSR Update Performance

Frequent DOM updates can cause UI lag. Implement these practices to keep your client-side updates performant: