Categories
React Tips

React Tips — Basic Hooks

Spread the love

React is one of the most popular libraries for creating front end apps. It can also be used to create mobile apps with React Native.

In this article, we’ll look at some basic hooks that are built-into React to make our function components smart.

State and useState

We can use the useState hook to store the state of our app. Therefore, it’s a basic building block of a smart React function component.

To use it, we write the following code:

import React from "react";

export default function App() {
  const [count, setCount] = React.useState(0);

  return (
    <>
      <button onClick={() => setCount(count => count - 1)}>decrement</button>
      <p>{count}</p>
    </>
  );
}

In the code above, we have the count state returned as the first element of the array returned by the useState hook.

We then defined an onClick handler which calls the setCount function returned as the 2nd element in the array returned by useState .

In there, we updated the count by returning the existing count value minus 1.

This lets us modify a state’s value based on its previous value. We can also pass in whatever we want to set directly if it doesn’t depend on the previous value of a state.

Passing in a callback will guarantee that the update is done based on the previous value of the state.

For instance, we can pass in a value directly into the state change function as follows:

import React from "react";

export default function App() {
  const [text, setText] = React.useState("foo");

  return (
    <>
      <button onClick={() => setText("foo")}>foo</button>
      <button onClick={() => setText("bar")}>bar</button>
      <button onClick={() => setText("baz")}>baz</button>
      <p>{text}</p>
    </>
  );
}

In the code above, we have 3 buttons that have click handlers that call setText to set the value of the text state.

Since the value we set doesn’t depend on the previous value, we can just set it directly by passing in the value that we want to set the value of text to.

The state change function can be used more than once, as we can see from the previous example.

It can accept any kind of value, including primitive values and objects.

Side effects and useEffect

The React useEffect hook is another important hook that we can’t overlook.

It’s used to commit side effects like updating data asynchronously from an API or working with the DOM.

Side effects are actions that can change our component in an unpredictable fashion.

It accepts a callback function that is run during every render. To restrict the callback to run only when a specified value is changed, we pass in a second argument with an array of the value that we want to watch and run the callback when they change.

If we pass in an empty array as the 2nd argument, then the callback only runs when during the first render.

For instance, we can use it as follows:

import React, { useEffect } from "react";

export default function App() {
  const [name, setName] = React.useState("");
  const [data, setData] = React.useState({});

  const getData = async () => {
    const res = await fetch(`https://api.agify.io/?name=${name}`);
    const d = await res.json();
    setData(d);
  };

  useEffect(() => {
    getData();
  }, [name]);

  return (
    <>
      <input value={name} onChange={e => setName(e.target.value)} />
      <p>
        {data.name} {data.age}
      </p>
    </>
  );
}

In the code above, we have an input that changes the value of the name state as we type something in it.

Then with the useEffect hook, we watch for changes in name so that getData is called when the name value changes.

In the getData function, we call setData to set the data and display the data that’s obtained from the API call.

We should just pass in an array as the 2nd argument always so that the callback won’t run during every render accidentally.

If we need to do clean up, we should return a function inside the useEffect callback and run any cleanup code inside the callback if needed.

We can use add clean up code as follows:

import React, { useEffect } from "react";

export default function App() {
  const [mousePosition, setMousePosition] = React.useState({});
  const { x, y } = mousePosition;

  const handleMouseMove = event => {
    const { pageX, pageY } = event;
    setMousePosition({
      x: pageX,
      y: pageY
    });
  };

  useEffect(() => {
    window.addEventListener("mousemove", handleMouseMove);

    return () => window.removeEventListener("mousemove", handleMouseMove);
  });

  return (
    <>
      <p>
        ({x}, {y})
      </p>
    </>
  );
}

In the code above, we added an event handler for the mousemove event called handleMousemove , which takes the mouse position and calls setMousePosition to set the mousePosition state.

We then watch the mouse position by writing:

window.addEventListener("mousemove", handleMouseMove);

in the useEffect callback. Below it, we have:

return () => window.removeEventListener("mousemove", handleMouseMove);

to remove the mousemove event listener when the App component is no longer being rendered.

Conclusion

The useState and useEffect hook are the 2 most useful and basic hooks in the React standard library.

They let us update state and commit side effects respectively.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *