Back
My 5 cents about React Hooks
Published On: May 26
#javascript#react#webdev

Hey guys, how are you doing?

I'll shortly tell about my experience with React Hooks.

Sometimes I accept external projects to work on and I use it as an opportunity to learn new things, test new stuff. Right now I'm working on a mobile project using React Native and I'm using this opportunity to learn React Hooks and Context.

At first time reading the React Hooks introduction, I was a bit confused about what is Hooks and how it works. So I decided to just jump in and try to use it.

What I've learn about it:

  • React Hooks is a way to "shortener" your code
  • Use more function components and less classes
  • Easier to share and reuse stateful logic

Let's see those points in a real world.

React Hooks is a way to “shortener” your code

Lets say that you have a form and you need to store the form data and submit it when user click on the button. In a "not React Hooks" environment, would be something like:

import React from 'react'

class MyForm extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      data: {}
    }
  }

  handleChange = (name, value) => {
    const { data } = this.state

    this.setState({
      data: {
        ...data,
        [name]: value
      }
    })
  }

  handleSubmit = (e) => {
    e.preventDefault()
    const { data } = this.state

    MyAPI.doSomething(data)
  }

  render() {
    const { data } = this.state

    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" value={data.name} onChange={e => this.handleChange('name', e.target.value)} />
        <input type="text" value={data.email} onChange={e => this.handleChange('email', e.target.value)} />

        <button type="submit">Submit data</button>
      </form>
    )
  }
}

This is how it will looks like using Hooks:

import React, { useState } from 'react'

const MyForm = () => {
  const [data, setData] = useState({})

  handleChange = (name, value) => setData(prev => ({ ...prev, [name]: value }))

  handleSubmit = (e) => {
    e.preventDefault()

    MyAPI.doSomething(data)
  }

  return (
    <form onSubmit={this.handleSubmit}>
      <input type="text" value={data.name} onChange={e => handleChange('name', e.target.value)} />
      <input type="text" value={data.email} onChange={e => handleChange('email', e.target.value)} />

      <button type="submit">Submit data</button>
    </form>
  )
}

Can you see the difference? From 42 lines to 22 lines.
Basically, when you write:

const [data, setData] = useState({})

You are doing something like:

constructor(props) {
  super(props)
  this.state = {
    data: {} // Initiating the data state as an empty object
  }
}
render () {
  const { data } = this.state // Getting the data key from state
}
AND
// Creating a kind of "helper" to set the state
const setData = data => this.setState({ data })

Use more function components and less classes

Using Hooks you don't need to have a lot of classes, you can do everything using function components!

Let's say that you need to track some props and do something if it changes. Without Hooks you would do something like:

import React from 'react'

class MyComponent extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.name !== prevProps.name) {
      console.log('NAME CHANGED')
    }
  }

  render() {
    const { name, email } = this.props

    return (
      <div>
        <p>Your name is: {name}</p>
        <p>Your email is: {email}</p>
      </div>
    )
  }
}

In Hooks we use the useEffect function to do that:

import React, { useEffect } from 'react'

const MyComponent = ({ name, email }) => {
  useEffect(() => {
    console.log('NAME CHANGED')
  }, [name])

  return (
    <div>
      <p>Your name is: {name}</p>
      <p>Your email is: {email}</p>
    </div>
  )
}

What i'm doing here:

useEffect(() => { // useEffect needs to receive a function as param
  console.log(NAME CHANGED) // Do something
}, [name]) // When the variable "name" changes.

I could also add another variable to the array, this would track it too, for example:

useEffect(() => {
  console.log(NAME OR EMAIL CHANGED)
}, [name, email]) // When the variable "name" OR "email" changes.

But in this case, I don't know which one changed. So, using Hooks you can separate it, you can have multiple useEffect:

useEffect(() => {
  console.log(NAME CHANGED)
}, [name])
useEffect(() => {
  console.log(EMAIL CHANGED)
}, [email])

And now you can do things separately depending on what variable changed.

Another important change using Hooks is the componentDidMount function. It is a function that executes once, usually to load data or set initial stuff.

Using Hooks there is a trick:

useEffect(() => {
  console.log(I WILL APPEAR JUST ONCE)
}, []) // Passing an empty array

Passing an empty array to the second param. This will be executed only once.

Easier to share and reuse stateful logic

Using Hooks you can extract the component logic to a custom hook and use it everywhere!

I won't talk about this topic with examples in this article because it can be very complex, so I do prefer to talk about it in another article.

But if you want to know more about it, you can check the documentation. It's awesome and very clear!

I'm enjoying using React Hooks so far. I had some trouble to understand it at the beginning but now it looks more clear to me.

I hope you guys enjoy my experience with Hooks and learn something from this.

If you have any question, please comment below! I'd be glad to help!

That’s all, folks!

Dev.to