react-hooks/todo
Report valid syntax that the React Compiler does not support yet
The React Compiler doesn't handle all of JavaScript yet. When it finds something it can't handle in a component or hook, it skips that function. The code is valid and still works, but it gets no automatic memoization. Turn this rule on to find those components.
Some of what it reports:
trywithfinally, andthrowinsidetryvar??=,||=and&&=count++on a variable that a nested function also usesthis, class expressions, and getters in object literals- BigInt literals, tagged templates with
${}, dynamicimport() for await, andfor (;;)without a condition
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"react-hooks/todo" = "error" # or "warn"Examples#
Reported:
function Report({ load }) {
let rows = [];
try {
rows = load();
} finally {
log("loaded");
}
return <Table rows={rows} />;
}function Report(props) {
let rows = props.rows;
rows ??= [];
return <Table rows={rows} />;
}function Report({ rows }) {
let clicks = 0;
const onClick = () => {
clicks++;
};
return <Table rows={rows} onClick={onClick} />;
}Not reported:
function Report({ load }) {
let rows = [];
try {
rows = load();
} catch (error) {
rows = [];
}
log("loaded");
return <Table rows={rows} />;
}function Report(props) {
const rows = props.rows ?? [];
return <Table rows={rows} />;
}A function that's neither a component nor a hook is never compiled, so it can use anything:
function loadRows(load) {
try {
return load();
} finally {
log("loaded");
}
}When not to use it#
If you don't use the React Compiler, there's nothing to fix here. Even if you do, rewriting working code is only worth it for components that are slow to render.