React best practices and patterns to reduce code - Part 2

React best practices and patterns to reduce code - Part 2

ยท

5 min read

I've another article about React's best practices and patterns to reduce code. It's a good article to read before you start to write your own React code.

React best practices and patterns to reduce code - Part 1

React best practices and patterns to reduce code

Without wasting time, let's look at some more best practices and patterns to reduce code. We'll start with the most common ones.

Use the self-closing tag if the component doesn't have children's props.

return <Component></Component>;
Good code:
return <Component />;

Don't write functions inside jsx elements.

return (
  <div>
    <button
      onClick={() => {
        setCount(1);
        // ...
      }}
    >
      Click
    </button>
  </div>
);
Good code:
const onClick = useCallback(() => {
  setCount(1);
  // ...
}, [deps]);

return (
  <div>
    <button onClick={onClick}>Click</button>
  </div>
);

Use object state if you have to update multiple states together.

Avoid using multiple setState calls in a row. This is a common mistake that can lead to a lot of unnecessary re-renders. It's better to use a single setState call.

const [count, setCount] = useState(0);
const [name, setName] = useState("");

const onClick = () => {
  setTimeout(() => {
    setName("John");
    setCount(count + 1);
  }, 1000);
};
Good code:
const [state, setState] = useState({
  count: 0,
  name: "",
});

const onClick = () => {
  setTimeout(() => {
    setState((prevState) => ({
      ...prevState,
      name: "John",
      count: prevState.count + 1,
    }));
  }, 1000);
};

Note: React 18 adds automatic batching, so multiple updates will be taken care of by react itself.


Use styled components to style your components. This is a good way to avoid writing CSS in JSX and also helps to avoid CSS setup for the application.

It's completely opinion based.

return <div style={{ backgroundColor: "red" }}></div>;
Good code:
const Container = styled.div`
  background-color: ${({ theme }) => theme.colors.background};
  padding: 1rem;
`;
Better code:
const getPrimaryColor = ({ theme }) => theme.colors.primary;
const getDefaultColor = ({ theme }) => theme.colors.secondary;

const Button = styled.button`
  background-color: ${getPrimaryColor};
  color: ${getDefaultColor};
`;

Note: Create functions to get color and other styles from the theme and pass them to styled-components. This will also help to reduce code.


Try to avoid class-based components and use functional components instead.

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
    this.onClick = this.onClick.bind(this);
  }

  onClick = () => {
    this.setState({
      count: this.state.count + 1,
    });
  };

  render() {
    return <button onClick>Click me</button>;
  }
}
Good code:
const Counter = () => {
  const [count, setCount] = useState(0);
  const onClick = () => setCount(count + 1);
  return <button>Click me</button>;
};

NOTE: Functional components not only reduces development time and code but also decrease production bundle size. It reduces the bundle size by almost ~60%.


React.memo to avoid unnecessary re-renders.

return (
  <ui>
    {items.map((item) => (
      <Component>{item}</Component>
    ))}
  </ui>
);
Good code:
const MemoComponent = React.memo(Component);
return (
  <ui>
    {items.map((item) => (
      <MemoComponent>{item}</MemoComponent>
    ))}
  </ui>
);

NOTE: Use React.memo() wisely, don't use memo where the component often re-renders with props.


Use JSX ShortHand, Try to use JSX shorthand for passing boolean variables.

return <button disabled={true}>Submit</button>;
Good code:
return <button disabled>Submit</button>;

Use the ternary operator instead of the if-else statement.

if (isLoading) {
  return <div>Loading...</div>;
} else {
  return <div>Data</div>;
}
Good code:
return isLoading ? <div>Loading...</div> : <div>Data</div>;

Use object(Map) instead of the switch statement. I've already mentioned the same in my previous article for reducers.

switch (props.type) {
  case "ADMIN":
    return <Admin />;
  case "USER":
    return <User />;
  default:
    return <NotFound />;
}
Good code:
const componentMap = {
  ADMIN: Admin,
  USER: User,
  NOT_FOUND: NotFound,
};

const Component = componentMap[props.type];
return <Component />;
Better code:
const componentMap = {
  ADMIN: React.lazy(() => import("../components/Admin")),
  USER: React.lazy(() => import("../components/User")),
  NOT_FOUND: React.lazy(() => import("../components/NotFound")),
};

const Component = componentMap[props.type];
return <Component />;

Use object destructuring instead of passing multiple props by name to a component.

const { name, age, role } = props;
return (
  <>
    <Component name={name} age={age} role={role} />
  </>
);
Good code:
return (
  <>
    <Component {...props} />
  </>
);

Don't need curly braces when you won't pass the string to a component.

return <Component name={"John"} />;
Good code:
return <Component name="John" />;

Don't use react element props like className, style etc for component custom props.

return (
  <Component style="bordered">
);
Good code:
return (
  <Component variant="bordered">
);

Use fragments instead of HTML elements like div, span, etc.

return (
  <div>
    <span>{props.name}</span>
    <span>{props.age}</span>
  </div>
);
Good code:
return (
  <>
    <span>{props.name}</span>
    <span>{props.age}</span>
  </>
);

Don't use the else block if if block returns something.

if (props.name) {
  return <div>{props.name}</div>;
} else {
  return <div>No name</div>;
}
Good code:
if (props.name) {
  return <div>{props.name}</div>;
}
return <div>No name</div>;

Use React.ragment instead of Html elements like div, span, etc

return (
  <container>
    {list.map((item) => (
      <div key={item.id}>
        <SomeComponent />
        <SomeAnotherComponent />
      </div>
    ))}
  </container>
);
Good code:
return (
  <>
    {list.map((item) => (
      <React.Fragment key={item.id}>
        <SomeComponent />
        <SomeAnotherComponent />
      </React.Fragment>
    ))}
  </>
);

Thank you for reading ๐Ÿ˜Š

Got any questions or additional? please leave a comment.

Must Read If you haven't
Javascript Promise Methods with polyfill example: A Cheat Sheet for Developer
React.js state management using signals
useAsync hook with cache

More content at hashnode.
Catch me on: Github, Twitter, LinkedIn, Medium, Dev.to, Blogspot, Stackblitz

Did you find this article valuable?

Support Rahul Sharma by becoming a sponsor. Any amount is appreciated!

ย