avoidAdjustingStateWhenAPropChangesAvoid adjusting state when a prop changes. Instead, adjust "{{state}}" directly during render when {{props}} changes, or refactor your state to avoid this need entirely.small-rules/no-adjust-state-on-prop-changeDisallow adjusting state in an effect when a prop changes.
Ported from
eslint-plugin-react-you-might-not-need-an-effect/no-adjust-state-on-prop-change.
The upstream rule points at the “Adjusting some state when a prop
changes”
section of the React docs.
It flags an effect whose dependencies include a prop, and whose body synchronously writes state. It’s a prop-to-state sync. It costs two renders. The prop arrives and you render with the old state. Then the effect runs and you render again with the fixed one. During that gap, the UI shows state that’s already wrong. On Roblox that shows up as a textlabel or a frame popping in a frame late.
The fix is to not copy the prop into state at all. Compute what you need during render and let the prop stay the source of truth. If the state has its own lifecycle, there are better tools than an effect for resetting it. More often the state shouldn’t exist.
avoidAdjustingStateWhenAPropChangesAvoid adjusting state when a prop changes. Instead, adjust "{{state}}" directly during render when {{props}} changes, or refactor your state to avoid this need entirely.This rule accepts one options object after the severity.
import React, { useEffect, useState } from "@rbxts/react";
export function List({ items }: { items: ReadonlyArray<string> }): React.Element { const [selection, setSelection] = useState<string | undefined>();
useEffect(() => { setSelection(undefined); }, [items]);
return <textlabel Text={selection} />;}import React, { useState } from "@rbxts/react";
export function List({ items }: { items: ReadonlyArray<string> }): React.Element { const [selection, setSelection] = useState<string | undefined>(undefined); const [previousItems, setPreviousItems] = useState(items);
if (items !== previousItems) { setPreviousItems(items); setSelection(undefined); }
return <textlabel Text={selection} />;}