# A React Effect that only sets state from other values

*Code longer than it needs to be*: one of the ways AI coding agents bloat software, from lessloc's [pattern catalog](https://lessloc.org/patterns/index.md). lessloc catches it as [`simpler`](https://lessloc.org/guide/reference.md#tier-2).

## What makes a React Effect that only sets state from other values a bad practice?

The standard that calls it a bad practice: React docs: "You Might Not Need an Effect".

## What does lessloc do about a React Effect that only sets state from other values?

lessloc catches it as [`simpler`](https://lessloc.org/guide/reference.md#tier-2).

- `simpler` (tier 2): Brute-force code with a shorter idiom: `== True`, an if/else that returns the condition, an index loop that only reads `xs[i]`, `.filter(...).length > 0`, a catch that only rethrows, a flag loop that is `any()`, a hand-built counter, an `__init__` that `@dataclass` writes, a React Effect that only sets state. ruff and clippy add more.

## Examples

Caught as `simpler`:

```jsx [ba.jsx]
import { useEffect, useState } from "react";
export function Cart({ items }) {
  const [total, setTotal] = useState(0);
  useEffect(() => {
    setTotal(items.reduce((s, i) => s + i.price, 0));
  }, [items]);
  return <p>{total}</p>;
}
```

Written well:

```jsx [ba.jsx]
import { useEffect, useState } from "react";
export function Theme() {
  const [theme, setTheme] = useState("light");
  useEffect(() => {
    setTheme(localStorage.getItem("theme") ?? "light");
  }, []);
  return <p>{theme}</p>;
}
```

## Related patterns

The other patterns in [Code longer than it needs to be](https://lessloc.org/patterns/index.md#code-longer-than-it-needs-to-be):

- [Brute-force idioms](https://lessloc.org/patterns/brute-force.md): lessloc catches it as `simpler`, built in for Python, JS/TS, Go, Rust, Java and C#. ruff (in every hook) and clippy (in `ci`) go deeper.
- [Hand-built counters and flag loops](https://lessloc.org/patterns/counters-and-flags.md): lessloc catches it as `simpler`.
- [A catch that only rethrows](https://lessloc.org/patterns/catch-rethrow.md): lessloc catches it as `simpler`.
- [A promise wrapped in new Promise](https://lessloc.org/patterns/promise-wrap.md): lessloc catches it as `simpler`.
- [Annotating types the compiler infers](https://lessloc.org/patterns/inferred-types.md): lessloc catches it as `simpler`.
- [Functions with many parameters (8 or more)](https://lessloc.org/patterns/long-params.md): lessloc catches it as `long-params`.
- [Deep nesting](https://lessloc.org/patterns/deep-nesting.md): lessloc catches it as `deep-nesting`.
- [Long functions](https://lessloc.org/patterns/long-function.md): lessloc catches it as `long-function`.
- [If-chains on literal values](https://lessloc.org/patterns/if-chain.md): lessloc catches it as `if-chain`.
- [A file that keeps growing](https://lessloc.org/patterns/swollen-file.md): lessloc catches it as `swollen-file`.
- [Reformatting lines the task did not change](https://lessloc.org/patterns/churn.md): lessloc gives every session a rule against it and catches it as `churn`.
- [Net growth past a budget](https://lessloc.org/patterns/net-growth.md): lessloc catches it as `net-growth`.
- [Golfed code](https://lessloc.org/patterns/golfed-code.md): lessloc catches it as `clever` and `dense-lines`.
