React this In A Function Component
ID |
javascript.react_this_in_function_component |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
best-practice, react, reliability |
Description
Reports this used inside a React function component — a function with a capitalised name that returns markup.
An arrow function does not bind a this of its own, so a this inside a callback written in the component belongs to the component and is reported too. A nested function expression or a method does bind one, and ends the search. A method is never reported, however it is named and whatever it returns, because a method has an instance by definition.
Rationale
// Bad — left over from a class component
function Panel(props) {
return <div title={this.props.title} role="group" />;
}
-
A function component is called, not constructed: React invokes it as a plain function and passes the props as its first argument.
-
thisis therefore whatever the call site makes it —undefinedin a module, which is what every bundled build produces.this.propsthrows "Cannot read properties of undefined" on the first render, and the error names the property rather than the mistake. -
It appears while converting a class component to a function: the body is copied, the
render()wrapper goes away, and thethis.prefixes are left behind.
Remediation
Read the props from the parameter, and keep per-render values in local variables or hooks.
import { useRef, useState } from "react";
// Good
function Panel({ title }) {
return <div title={title} role="group" />;
}
// Good — state and refs come from hooks, not from an instance
function Counter() {
const [count, setCount] = useState(0);
const input = useRef(null);
return <input ref={input} value={count} onChange={() => setCount(count + 1)} />;
}