avoidChainingStateUpdatesAvoid chaining state changes. When possible, update "{{state}}" along with other relevant state simultaneously.small-rules/no-chain-state-updatesDisallow chaining state changes in an effect.
Ported from
eslint-plugin-react-you-might-not-need-an-effect/no-chain-state-updates.
The upstream rule points at the “Chains of
computations” section of the
React docs, so that’s where the intent comes from.
This flags the shape where an effect depends on state and then writes different state. State A changes, the effect runs, it sets state B, you render again. That’s a chain, and chains are how one input change becomes four renders. If B happens to be in another effect’s dependencies, the chain keeps going.
The chain usually exists because someone wanted a computed value but reached for an effect instead of computing during render. Set both states where the change originates, or derive the follow-on value during render and skip the middleman. The rule can’t tell whether the chain is deliberate, say fetch-then-set, so treat it as a nudge to look rather than a verdict.
avoidChainingStateUpdatesAvoid chaining state changes. When possible, update "{{state}}" along with other relevant state simultaneously.This rule accepts one options object after the severity.
import React, { useEffect, useState } from "@rbxts/react";
export function Game(): React.Element { const [round, setRound] = useState(1); const [isGameOver, setIsGameOver] = useState(false);
useEffect(() => { if (round > 10) { setIsGameOver(true); } }, [round]);
return ( <frame> <textlabel Text={isGameOver} /> <textbutton Text={round} onActivated={() => setRound(round + 1)} /> </frame> );}import React, { useState } from "@rbxts/react";
export function Game(): React.Element { const [round, setRound] = useState(1); const [isGameOver, setIsGameOver] = useState(false);
function handleRoundComplete(): void { const nextRound = round + 1; setRound(nextRound); if (nextRound > 10) { setIsGameOver(true); } }
return ( <frame> <textlabel Text={isGameOver} /> <textbutton Text={round} Event={{ Activated: handleRoundComplete }} /> </frame> );}