I keep hearing about how React Hooks is the direction where Facebook wants the React library to go. So, I wanted to take an existing project of mine and convert a Class component to a Functional component that uses the useState
React Hook. Let's take a look at the Class component.
The Class Component Version
import React, { Component } from 'react'
export class RecipesInput extends Component {
state = {
recipe: ""
}
handleChange = event => {
this.setState({ [event.target.name]: event.target.value })
}
handleSubmit = event => {
event.preventDefault()
this.props.fetchRecipes(this.state)
}
render() {
return (
<div>
<h2>Recipes Search Bar</h2>
<form onSubmit={this.handleSubmit}>
<input name="recipe" type="text" value={this.state.recipe} onChange={this.handleChange}/>
<input type="submit" value="Search!"/>
</form>
</div>
)
}
}
export default RecipesInput
Standard stuff. It's a form that takes a user's input, store the changes in the local state, then submit the state upon onSubmit
. Let's change it up.
//class
import React, { Component } from 'react'
export class RecipesInput extends Component {
state = {
recipe: ""
}
...
//functional
import React, { useState } from "react"
export default function RecipesInput(props) {
const [recipe, setRecipe] = useState("")
...
I don't import {Component}
. Removed the local state. I import {useState}
, a React Hook. Then call this hook according to the official doc. I have a dispatch action being passed down to this component from the parent container component. We'll comeback to this.
The biggest change is obviously the hook. On the left side, you declare the name of the state, then the name of the method to modify it. On the right side, you call the Hook you want to use, then feed it the initialState(An empty string in this case).
//class
handleChange = event => {
this.setState({ [event.target.name]: event.target.value })
}
render() {
return (
<div>
<h2>Recipes Search Bar</h2>
<form onSubmit={this.handleSubmit}>
<input name="recipe" type="text" value={this.state.recipe} onChange={this.handleChange}/>
<input type="submit" value="Search!"/>
</form>
</div>
)
}
//functional
return (
<div>
<h2>Recipes Search Bar</h2>
<form onSubmit={handleSubmit}>
<input
name="recipe"
type="text"
value={recipe}
onChange={event => {
setRecipe(event.target.value)
}}
/>
<input type="submit" value="Search!" />
</form>
</div>
)
render()
turns into return()
. There's no longer any mention of this
. The biggest change here is the onChange
for the text input.
Instead of using handleChange
and this.setState
to update the local state upon the input's change, we can just call the hook we set up with setRecipe
. Then, we feed it the updated value, which we're grabbing from the input bar itself.
The last part is to modify the handleSubmit
. All we have to do is remove this
.
const handleSubmit = event => {
event.preventDefault()
props.fetchRecipes(recipe)
}
Final Product
import React, { useState } from "react"
export default function RecipesInput(props) {
const [recipe, setRecipe] = useState("")
const handleSubmit = event => {
event.preventDefault()
props.fetchRecipes(recipe)
}
return (
<div>
<h2>Recipes Search Bar</h2>
<form onSubmit={handleSubmit}>
<input
name="recipe"
type="text"
value={recipe}
onChange={event => {
setRecipe(event.target.value)
}}
/>
<input type="submit" value="Search!" />
</form>
</div>
)
}
Top comments (0)