the state methods can be replaced with React hooks, specifically, the useState hook
I'll recommend you to check the docs, but the main points to keep in mind are
- there's no
this (so no more .bind(this)!)
- everything are functions
and the rules of hooks
- hooks can only be called from react functions (not from plain
js functions). That is, call them from functional components, or other hooks
- hooks have to be called always in the same order, meaning you can't conditionally call hooks (like inside an
if) nor in loops). Because of this, they have to also be called in the "top" level of the component (meaning, they can't be called inside a function defined in your component)
With that in mind, let's see how you'd replace the state. To do so, you can use the useState hook.
const [displayCategory, setDisplayCategory] = useState('all');
The unique parameter is the initialValue for your state. This one is optional, if no default value is provided, it would be the same as providing undefined.
As you can see, it returns an array of two elements, what we are doing here is destructuring; it's the same as doing
const stateHook = useState('all')
const displayCategory = stateHook[0]
const setDisplayCategory= stateHook[1]
That means you can name whatever you want those variables.
Now, displayCategory is your actual state value. You can use it as you'd use this.state.displayCategory. And setDisplayCategory is the function that lets you update your state.
One of the differences to keep in mind is that the functions to update the state in hooks will override the entire state - meaning there's no merging of state as there was in classes. This is especially important for objects. So something like this
const [state, setState] = useState({ foo: 1, baz: 2 })
// later in one event
setState({ baz: 3 })
There, on the next render, the value of state will be { baz: 3 } - the previous was lost
In order to preserve the state, the second parameter from the array returned from useState (meaning, the setState, setDisplayCategory, or whatever you call it), accepts a callback in which you can manually do the merging of properties. Like this
setState(prevState => ({ ...prevState, baz: 3 })
Now, in the next render, the value of your state will be { foo: 1, baz 3 }
Modeling complex states
Before hooks, you could only have one state. Therefore, everything you wanted to store in your state had to belong to this unique object. However, with hooks, you're allowed to have multiple states. For example, following your code, you could have something like this
const [displayCategory, setDisplayCategory] = useState('all')
const [products, setProducts] = useState([])
const [myComplexObject, setMyComplexObject] = useState({ foo: 1, baz: 2, bar: [1, 2, 3] })
Considering this, and the fact that the properties are not automatically merged, it's convenient to group state objects/variables/properties that change together under the same useState object. This gives more flexibility, especially when passing different portions of your state to different child components - you could save some rerenders when, for those components, the props don't change