# You probably don't need useEffect for that

`useEffect` is for synchronizing your component with something outside React: the network, the DOM, a subscription. Most of the effects I see in code reviews are doing neither. They are computing values or responding to clicks, and they would be simpler, faster, and less buggy without an effect at all.

## You don't need an effect to transform data for rendering

A common pattern:

```jsx
const [posts, setPosts] = useState([]);
const [visible, setVisible] = useState([]);

useEffect(() => {
  setVisible(posts.filter((p) => !p.archived));
}, [posts]);
```

This runs an extra render every time `posts` changes: one to set `posts`, another to set `visible`. Just compute it during render:

```jsx
const [posts, setPosts] = useState([]);
const visible = posts.filter((p) => !p.archived);
```

If the filter is genuinely expensive, reach for `useMemo`, not state plus an effect. Derived values should be derived, not stored.

## You don't need an effect to handle an event

Another one:

```jsx
useEffect(() => {
  if (submitted) {
    showToast("Saved");
    setSubmitted(false);
  }
}, [submitted]);
```

The toast is a reaction to a user action, so put it in the handler where the action happens:

```jsx
function handleSubmit() {
  save();
  showToast("Saved");
}
```

The effect version adds a state variable, an extra render, and a flag you have to reset. The handler version is three lines and obvious.

## When an effect is the right tool

Use it when you are reaching outside React and need to clean up after yourself:

```jsx
useEffect(() => {
  const socket = connect(roomId);
  socket.on("message", onMessage);
  return () => socket.close();
}, [roomId]);
```

This is a real synchronization: a live connection that must open when `roomId` changes and close when the component unmounts. The cleanup function is the tell. If your effect has nothing to clean up and only sets state, that is a strong hint it should not be an effect.

## A quick checklist

Before writing `useEffect`, ask:

1. Can I compute this during render instead? Then do that.
2. Is this responding to a specific user action? Move it to the handler.
3. Am I syncing with something external that needs cleanup? Then an effect is correct.

> Effects are an escape hatch from React, not a place to put logic that React can already handle.

Fewer effects means fewer renders, fewer race conditions, and code that is far easier to follow.
