DEV Community

Cover image for Opinionated React: Use State Colocation
faraz ahmad
faraz ahmad

Posted on • Edited on

8 2

Opinionated React: Use State Colocation

Intro

I’ve been working with React for over four years. During this time, I’ve formed some opinions on how I think applications should be. This is part 4 in the series of such opinionated pieces.

Why

State location helps reduce the complexity of your application. In some cases, it can actually improve performance.

What does colocate your state mean?

Simply put, it means to put your state as close to where it's being used. You should avoid global state unless it's absolutely necessary.

An example

Here's some code that I've come across several times in my career. I would avoid doing this.

import * as React from "react";

interface PersonFormState {
  firstName: string;
  lastName: string;
}

interface PersonFormAction {
  type: "SET_VALUE";
  payload: { [name: string]: string };
}

function personFormReducer(state: PersonFormState, action: PersonFormAction) {
  switch (action.type) {
    case "SET_VALUE": {
      return { ...state, ...action.payload };
    }
    default: {
      return state;
    }
  }
}

export const PersonFormContainer: React.FC = () => {
  const [state, dispatch] = React.useReducer(personFormReducer, {
    firstName: "",
    lastName: ""
  });

  const handleChange = (name: string, value: string) => {
    const updatedValue = { [name]: value };
    return dispatch({ type: "SET_VALUE", payload: updatedValue });
  };

  return <PersonForm values={state} onChange={handleChange} />;
};

interface PersonFormProps {
  values: {
    firstName: string;
    lastName: string;
  };
  onChange: (name: string, value: string) => void;
}

const PersonForm: React.FC<PersonFormProps> = ({ values, onChange }) => {
  return (
    <form>
      <label htmlFor="firstName">First name</label>
      <input
        name="firstName"
        value={values.firstName}
        onChange={event => onChange(event.target.name, event.target.value)}
      />
      <label htmlFor="lastName">Last name</label>
      <input
        name="lastName"
        value={values.lastName}
        onChange={event => onChange(event.target.name, event.target.value)}
      />
    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

I find this code overcomplicated and hard to follow. It's also good to note that this will perform poorly, because we are causing a re-render of our entire state tree every time an input's value changes.

Use colocation to simplify your code.

Here's how I would write this.

import * as React from "react";

export const PersonForm: React.FC = () => {
  return (
    <form>
      <label htmlFor="firstName">First name</label>
      <PersonInput name="firstName" />
      <label htmlFor="lastName">Last name</label>
      <PersonInput name="lastName" />
    </form>
  );
};

interface PersonInputProps {
  name: string;
}

const PersonInput: React.FC<PersonInputProps> = ({ name }) => {
  const [value, setValue] = React.useState("");

  return (
    <input
      name={name}
      value={value}
      onChange={event => setValue(event.target.value)}
    />
  );
};
Enter fullscreen mode Exit fullscreen mode

I would always start with state colocation and then lift state when needed. Keep things simple!

Q&A

Every post I will answer a question I received on twitter. Here's this week's question.

There are very few things that I consider global. Most state should be colocated where it's being used. Here are a couple things that I consider global:

  • The current user
  • Language settings
  • A theme

Outside of these three, I'm not sure anything else needs to be global. 👍

Wrapping Up

This is the 4th installment in a series of pieces I will be writing. If you enjoyed this, please comment below. What else would you like me to cover? As always, I’m open to feedback and recommendations.

Thanks for reading.

P.S. If you haven’t already, be sure to check out my previous posts in this series:

  1. An Opinionated Guide to React: Folder Structure and File Naming
  2. An Opinionated Guide to React: Component File Structure
  3. Opinionated React: State Management

Quadratic AI

Quadratic AI – The Spreadsheet with AI, Code, and Connections

  • AI-Powered Insights: Ask questions in plain English and get instant visualizations
  • Multi-Language Support: Seamlessly switch between Python, SQL, and JavaScript in one workspace
  • Zero Setup Required: Connect to databases or drag-and-drop files straight from your browser
  • Live Collaboration: Work together in real-time, no matter where your team is located
  • Beyond Formulas: Tackle complex analysis that traditional spreadsheets can't handle

Get started for free.

Watch The Demo 📊✨

Top comments (1)

Collapse
 
asifroyal profile image
Asif

I was looking for simple definition of state colocation and fortunately I came across your post. I liked your opinion.

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

If this post resonated with you, feel free to hit ❤️ or leave a quick comment to share your thoughts!

Okay