I have created a react functional HOC that works correctly, but violates the eslint rule react/display-name
. Here is the code:
export const withTheme = (WrappedComponent) => {
// eslint-disable-next-line react/display-name
return props => {
const ctx = useContext(ThemeContext)
return <WrappedComponent {...props} darkTheme={ctx.darkTheme} toggleTheme={ctx.toggleTheme}/>
}
}
If I fix it by naming the function like I think is the intent (as follows):
export const withTheme = (WrappedComponent) => {
return func;
function func(props) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const ctx = useContext(ThemeContext)
return <WrappedComponent {...props} darkTheme={ctx.darkTheme} toggleTheme={ctx.toggleTheme}/>
}
}
I get the eslint error react-hooks/rules-of-hooks
How can I fix this so I get the HOC to work (as it does) and not have any eslint errors?
CodePudding user response:
The rules of hooks that the linter enforces are:
Don't call Hooks from regular JavaScript functions. Instead, you can:
- Call Hooks from React function components.
- Call Hooks from custom Hooks
Your function func
looks, to the linter, like just a normal function - not a component, and as a result, it prohibits calling a hook (useContext
) inside it. If you change func
to Func
, the uppercase function name will then be recognized as a React component.
export const withTheme = (WrappedComponent) => {
return Func;
function Func(props) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const ctx = useContext(ThemeContext)
return <WrappedComponent {...props} darkTheme={ctx.darkTheme} toggleTheme={ctx.toggleTheme}/>
}
// or: return function Func(props) { ...
}
(though if you don't care for a name other than func
, some would argue that it'd make more sense to ignore react/display-name
here than to add less than meaningful code)