avoidInitializingStateAvoid initializing state in an effect. Instead, initialize "{{state}}"'s "useState()" with "{{arguments}}". For SSR hydration, prefer "useSyncExternalStore".small-rules/no-initialize-stateDisallow initializing state in an effect.
Ported from
eslint-plugin-react-you-might-not-need-an-effect/no-initialize-state.
The upstream rule points at TkDodo’s post on avoiding hydration mismatches with
useSyncExternalStore,
which is a web-React problem.
The shape is a mount-only effect that synchronously sets state. You already have a place for initial values:
the useState() initializer. An effect that initializes state means the first frame renders without the
value, then the effect fires and it pops in a frame later. On the web that’s also a hydration mismatch,
which is what the upstream link is about; roblox-ts has no server render, so that half doesn’t apply here,
but the initial-value problem is identical.
The one legitimate case is async initialization, you can’t await in an initializer, so the rule backs off when the state write happens inside an async callback. That’s the exception, not the rule.
avoidInitializingStateAvoid initializing state in an effect. Instead, initialize "{{state}}"'s "useState()" with "{{arguments}}". For SSR hydration, prefer "useSyncExternalStore".This rule accepts one options object after the severity.
import React, { useEffect, useState } from "@rbxts/react";
export function MyComponent(): React.Element { const [state, setState] = useState<string | undefined>();
useEffect(() => { setState("Hello"); }, []);
return <textlabel Text={state} />;}import React, { useEffect, useState } from "@rbxts/react";
declare const game: { readonly GetService: (service: string) => { readonly GetAsync: (url: string) => Promise<string> };};
export function MyComponent(): React.Element { const [state, setState] = useState<string | undefined>();
useEffect(() => { void (async (): Promise<void> => { const response = await game.GetService("HttpService").GetAsync("https://api.example.com/data"); setState(response); })(); }, []);
return <textlabel Text={state} />;}