Reputation: 272
I'm trying to use useDispatch
inside my component's render function.
import { useDispatch } from 'react-redux';
I have a input that tries to useDispatch on onChange
onChange={() => useDispatch()(update("test"))}
When onChange is fired, I get this error:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
import React, {
Component
} from 'react';
import {
useDispatch
} from 'react-redux';
import {
update
} from '../store/actions';
class Something extends Component {
render() {
return (<input onChange={() => useDispatch()(update("test"))}/>)
}
}
export default Something;
Upvotes: 4
Views: 10374
Reputation: 1075925
The problem is that you're using it in render
in a class component. You can't use hooks in class components. That's why the error message says
Invalid hook call. Hooks can only be called inside of the body of a function component.
(my emphasis). Class components aren't function components. (That's a bit easy to miss, would be good if the list of possible causes mentioned class components specifically.)
So you'd want to make it a function component:
import React, {
Component
} from 'react';
import {
useDispatch
} from 'react-redux';
import {
update
} from '../store/actions';
function Something() { // ***
return <input onChange={() => useDispatch()(update("test"))}/>; // ***
} // ***
export default Something;
Also note the warning in the documentation that the above will cause unnecessary rendering and that you should use useCallback
:
import React, {
Component,
useCallback
} from 'react';
import {
useDispatch
} from 'react-redux';
import {
update
} from '../store/actions';
function Something() {
const dispatch = useDispatch(); // ***
const handleChange = useCallback( // ***
() => dispatch(update("test")), // ***
[dispatch] // ***
); // ***
return <input onChange={handleChange}/>; // ***
}
export default Something;
Upvotes: 5
Reputation: 1877
Yes you are not using it correctly, try this:
const dispatch = useDispatch()
...
onChange={() => dispatch(update("test"))}
See documentation of useDispatch, there is example of its usage.
Upvotes: 0