Try @eslint-react/kit@beta โ†’
logoESLint React

no-unused-state

Warns about state variables that are defined but never used, or only used in effects.

This rule is experimental and may change in the future or be removed. It is not recommended for use in production code at this time.

Full Name in eslint-plugin-react-x

react-x/no-unused-state

Full Name in @eslint-react/eslint-plugin

@eslint-react/no-unused-state

Features

๐Ÿงช

Rule Details

This rule warns about state variables declared via useState (or similar state hooks) that are defined but never read, or only read inside an effect or effect dependency array. State that is only used in effects often indicates missing logic in the render output or a state value that can be derived from props instead.

Common Violations

Invalid

import { useState } from "react";

function Component() {
  const [data, setData] = useState(0);
  return <div />;
}
import { useEffect, useState } from "react";

function Component() {
  const [data, setData] = useState(0);
  useEffect(() => {
    console.log(data);
  }, [data]);
  return <div />;
}
import { useEffect, useState } from "react";

function Form({ firstName, lastName }) {
  // ๐Ÿ”ด Avoid: redundant state and unnecessary Effect
  const [fullName, setFullName] = useState("");
  useEffect(() => {
    setFullName(firstName + " " + lastName);
  }, [firstName, lastName]);
  // ...
}

Valid

import { useState } from "react";

function Component() {
  const [data, setData] = useState(0);
  return <div>{data}</div>;
}
import { useCallback, useState } from "react";

function Component() {
  const [data, setData] = useState(0);
  const handleClick = useCallback(() => {
    console.log(data);
  }, [data]);
  return <div onClick={handleClick} />;
}
function Form({ firstName, lastName }) {
  // โœ… Good: calculated during rendering
  const fullName = firstName + " " + lastName;
  // ...
}

Options

Shared Settings

Custom state and effect hooks can also be configured via shared ESLint settings, which apply consistently across all rules in the plugin:

{
  "settings": {
    "react-x": {
      "additionalStateHooks": "/^(useMyState|useCustomState)$/u",
      "additionalEffectHooks": "/^(useMyEffect|useCustomEffect)$/u",
    }
  }
}

Resources

On this page