Reputation: 738
I am new in react and trying to learn redux. I want to access the store inside a class, but it gives me an error the I cant use hook in class.
When I use this code in function (as I saw in a YouTube tutorial), it works without any problem. Here I access to counter in the store.
function App() {
const counter = useSelector(state => state.counter);
return <div>{counter}</div>;
}
but when I want to do this in class, it gives me an error that I can't use hooks in class.
So how can I access to my store either useSelector or useDispatch in class component?
Upvotes: 40
Views: 62292
Reputation: 754
use HOC (Higher Order Component), for me this is the simplest way to use hooks in class component
class MyComponent extends React.PureComponent {}
const MyHoc = () => {
const counter = useSelector();
return <MyComponent counter={counter} />
}
or there are some cases that you want to select state that accept arguments, you may still use mapState
const mapState = ({state}) => ({
getComments(post_id) {
return state.comments.find(cmts => cmts.post_id === post_id)
}
})
const connector = connect(mapState)(MyComponent)
and consume the function through this
const MyHoc = ({post_id, getComments}) => {
const comments = getComments(post_id)
const counter = useSelector();
// and use the comments somewhere
return <MyComponent counter={counter} />
}
export default connector(MyHoc)
Upvotes: 0
Reputation: 746
As @Ying Zuo said, your method works only with Functional Components. To solve this problem:
Instead of this line:
const counter = useSelector(state => state.counter);
You define the counter state like this:
const mapStateToProps = state => ({
counter: state.counter
});
Then for dispatching you should use it like this:
const mapDispatchToProps = () => ({
increment,
decrement
});
At the end you combine everything like this:
export default connect(
mapStateToProps,
mapDispatchToProps()
)(App);
Don't forget to import increment
and decrement
from your action
and connect
from the react-redux
module.
Upvotes: 43
Reputation: 9
class App extends Component {
constructor(props){
super(props)
this.state = {
reduxState : {}
}
}
DummyView = () => {
const reducer = useSelector(state => state.reducer)
useEffect(() => {
this.setState({
reduxState : reducer
})
}, [])
return null
}
render(){
return(
<this.DummyView/>
)
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Upvotes: 0
Reputation: 483
useSelector
and useDispatch
are React Hooks, which only work in function components.
https://reactjs.org/docs/hooks-overview.html#but-what-is-a-hook
With React Hooks, most components can and should be written with function components. If you have to write a class-based component, you can use connect
from react-redux.
https://blog.logrocket.com/react-redux-connect-when-and-how-to-use-it-f2a1edab2013/
Upvotes: 20