absolute/localize-react-props
Disallow variables that are only passed to a single custom child component; move them into that component instead.
#Rule Details
Encourages colocating state and data with the component that actually consumes it. If a variable — or a useState pair — is only ever passed to a single custom child, the rule suggests moving the declaration into that child instead of threading it through the parent as a prop.
For useState, both the state value and its setter must be used exclusively inside one custom (uppercase-tagged) child element before the rule fires. For plain variables, the rule waits until the end of the file and only reports a value when it is the sole candidate for a given child component — if two or more values flow to the same component, they are assumed to be settings that belong on the parent.
There are deliberate escape hatches: anything derived from a custom hook (useX) is exempt, usage on a native lowercase element counts as "used outside" and suppresses the report, and values passed to a *Provider/*Context value prop are ignored.
#Examples
State + setter to a single child
function Counter() {
const [count, setCount] = useState(0);
// Both state and setter only reach <Display /> → move them inside it
return <Display count={count} setCount={setCount} />;
}function Page() {
const heading = 'Welcome';
return (
<section>
<Header title={heading} /> {/* only consumer */}
</section>
);
}function Toolbar() {
const label = 'Save';
// Passed to two different children → assumed shared, not flagged
return (
<div>
<PrimaryButton text={label} />
<MenuItem text={label} />
</div>
);
}function Profile() {
const firstName = 'Ada';
const lastName = 'Lovelace';
// Two candidates for the same component → treated as parent-owned settings
return <NameTag firstName={firstName} lastName={lastName} />;
}Hook-derived values are exempt
function Feed() {
const data = useFetch('/api/posts'); // hook-derived
const posts = data.posts; // references a hook result → exempt
return <PostList posts={posts} />;
}#Configuration
Enable this rule in your ESLint configuration:
{
rules: {
'absolute/localize-react-props': 'error'
}
}#Related Rules
#When Not To Use It
Container/presentational architectures intentionally hoist state into a parent and pass it down to a single dumb child. If that pattern is core to your codebase, this rule will produce false positives — disable it or restrict it to leaf modules.