DEV Community

BebopVinh
BebopVinh

Posted on

First Time with React Hooks

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>
    )
}

React Hook Test Link

Top comments (0)