Skip to content
Sarj Code Standards

no-readonly-prop-state

Review props copied into state without a usable updater.

Why

State initialized from props retains the first render's value. Without an observed updater, later props can leave the displayed value stale and add a second source of truth.

Fix

Derive the value from current props when it should stay current. For an intentional mount-time snapshot, retain that lifecycle explicitly, for example with a ref; independently editable drafts keep their updater. Review the intended lifecycle before changing behavior.

Examples

Before — flagged A prop snapshot has no updater
src/status.tsx
import { useState } from "react";
export function Status({ status }: { status: string }) {
const [savedStatus] = useState(status);
return <p>{savedStatus}</p>;
}
tsconfig.json
{
"compilerOptions": {
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve"
},
"include": ["src/**/*"]
}
After — preferred Render the current prop directly
src/status.tsx
export function Status({ status }: { status: string }) {
return <p>{status}</p>;
}
tsconfig.json
{
"compilerOptions": {
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve"
},
"include": ["src/**/*"]
}

References