1 of 60

React: Common Mistakes in 2023

@housecor

reactjsconsulting.com

2 of 60

Foundation

State

JSX

Props

HTTP

Performance

Testing

File Structure

3 of 60

Foundation

4 of 60

5 of 60

Mistake: Using create-react-app

Solution: Vite, Next, Remix

6 of 60

7 of 60

Mistake�Separate repos for related code

Solution

Consider a monorepo (not company-wide)

Turborepo

npm/yarn/pnpm workspaces

8 of 60

Mistake�Not using TypeScript, Zod, msw, etc.

Solution

Use ‘em!

9 of 60

Mistake�Not using typescript-eslint

Solution

Use heavily, early

10 of 60

Mistake�Overspecifying types

Solution

Only specify when it can’t be inferred

11 of 60

Mistake�Lying to TypeScript

Solution

Be honest

Be clear

Create separate, well-named types

12 of 60

Mistake�Export default on separate line

Solution

Use func declaration

13 of 60

Mistake�Inconsistent order

14 of 60

JSX

15 of 60

Mistake�Overlooking reuse opportunities

Solution

Repeating JSX? Create a component.

Repeating logic? Create a hook.

16 of 60

Mistake�Weak/missing design system

Solution

Create design system first

17 of 60

Mistake�Repeated map calls

Solution

Map once

18 of 60

Mistake�Separate, small, single use functions

19 of 60

reactjsconsulting.com

20 of 60

State

21 of 60

Mistake�Separating related state

Solution

Unify related state

22 of 60

Mistake�Multiple setState calls in a row

Solution

Unify. Consider useReducer.

23 of 60

Mistake�Syncing state in useEffect

Solution

Derive state

24 of 60

Mistake�Fetching in useEffect

Solution

React query, RSC, swr, Apollo, loader…

25 of 60

Mistake�Using useEffect 😉

26 of 60

Mistake�Using the wrong type of state

Solution

Know the 8 ways to handle state

27 of 60

Mistake�State too high

28 of 60

Mistake�Sharable state in useState

Solution

Use the URL

29 of 60

Mistake�Clunky array updates

const toggleSelectedPlan = (plan: Plan) => {

const currentIndex = selectedPlans.findIndex(

(selectedPlan) => selectedPlan.id === plan.id

);

const newChecked = [...selectedPlans];

if (currentIndex === -1) {

newChecked.push(plan);

} else {

newChecked.splice(currentIndex, 1);

}

setSelectedPlans(newChecked);

};

const toggleSelectedPlan = (planId: number) => {

setSelectedPlanIds((prev) => {

if (prev.some((id) => id === planId)) {

return prev.filter((id) => id !== planId);

}

return [...prev, planId];

});

};

30 of 60

Mistake�Subset arrays

Solution

Consider one array

31 of 60

Mistake�Needless state

Solution

Doesn’t change? Use a const.

Doesn’t render? Use a ref.

32 of 60

Mistake�Global state overuse

Solution

Keep state as local as possible

33 of 60

Mistake�Separate, related State

Solution

Group via an object

34 of 60

Mistake�Repeated onChange handlers

Solution

Use computed property syntax

Use context with custom component

Use a form library

35 of 60

Mistake�Supporting impossible states

Solution

Make the impossible, impossible

36 of 60

Mistake�Poor error handling

Solution

Use react-error-boundary

Create granular boundaries

Handle async, event handlers too

37 of 60

Mistake�Naming things “data”

38 of 60

Props

39 of 60

Mistake�Optional props on single use component

Solution

Don’t. More here and here.

40 of 60

Mistake�Not naming vars to use object shorthand

Solution

Name consistently

41 of 60

HTTP

42 of 60

Mistake�Using fetch, Axios

Solution

Use ky

43 of 60

Mistake�Not caching HTTP calls

Solution

Use react-query, swr, Apollo client, etc

44 of 60

Performance

45 of 60

Mistake�useMemo, useCallback, etc everywhere

Solution

Use rarely as a last resort

42+ ways to make your React app faster

46 of 60

Styling

47 of 60

Mistake�Styling from scratch

Solution

Consider Tailwind, component libs

48 of 60

Mistake�No design system

Solution

Create one

49 of 60

Testing

50 of 60

Mistake�Not mocking

Solution

Use Mock Service Worker

51 of 60

Mistake�Not automating the browser

Solution

Use Cypress or Playwright

52 of 60

Mistake�Separate QA team

Solution

Collaborate, or better yet, integrate

53 of 60

File Structure

54 of 60

Mistake�Organizing files by “type”

Solution

Organize folders/files by page

Store related stuff together

55 of 60

Mistake�Few shared components

Solution

Create reusable components

Document them

Put them in a clear spot

56 of 60

Mistake�Formatting by hand

Solution

Run Prettier on save

Recommend via extensions.json

Configure CI to validate

57 of 60

Summary

58 of 60

reactjsconsulting.com

59 of 60

reactjsconsulting.com

60 of 60

reactjsconsulting.com

Consulting and training

pluralsight.com

Software courses

@housecor

Twitter