Categories
React Hooks

Top React Hooks — Promises, Tweens, and Manual Update

Spread the love

Hooks contains our logic code in our React app.

We can create our own hooks and use hooks provided by other people.

In this article, we’ll look at some useful React hooks.

react-use

The react-use library is a big library with many handy hooks.

useTween

The useTween hook animates a number between 0 and 1.

For instance, we can use it by writing:

import React from "react";
import { useTween } from "react-use";

export default function App() {
  const t = useTween();

  return <div>Tween: {t}</div>;
}

We just call the useTween hook to return the number being animated.

We can also set the easing, duration, and delay before the animation starts.

To do that, we write:

import React from "react";
import { useTween } from "react-use";

export default function App() {
  const t = useTween("inCirc", 5000, 500);

  return <div>Tween: {t}</div>;
}

The first argument is the easing name.

The names can be one of the ones in this list.

The 2nd is the duration of the animation.

The 3rd is the delay before running the animation.

The numbers are in milliseconds.

useUpdate

The useUpdate hook lets us return a function that forces a re-render when it’s called.

To use it, we can write:

import React from "react";
import { useUpdate } from "react-use";

export default function App() {
  const update = useUpdate();
  return (
    <>
      <div>{Date.now()}</div>
      <button onClick={update}>Update</button>
    </>
  );
}

We called the useUpdate hook to return the update function.

Then we passed that into the onClick handler.

useAsync

To run code that returns a promise cleanly, we can use the useAsync hook.

To use it, we write:

import React from "react";
import { useAsync } from "react-use";

export default function App() {
  const state = useAsync(async () => {
    const response = await fetch("https://api.agify.io/?name=michael");
    const result = await response.json();
    return result;
  }, []);

  return (
    <div>
      {(() => {
        if (state.loading) {
          return <div>Loading...</div>;
        }

        if (state.error) {
          return <div>Error</div>;
        }

        return <div>{JSON.stringify(state.value)}</div>;
      })()}
    </div>
  );
}

We called the useAsync hook with an async function as its callback.

Inside the callback, we return a promise by calling the fetch function and then returning the result from the response.

The 2nd argument of the hook is an array and lets us listen for value changes and reload if the value changes.

The hook returns the state object which has various properties.

loading indicates whether the promise is loading or not.

error indicates whether an error occurs.

value has the value resolved from the promise.

useAsyncFn

The useAsyncFn is similar to the useAsync hook.

The signature is the same as useAsync .

The difference is that it returns a function that lets us invoke the promise again.

For instance, we can write:

import React from "react";
import { useAsyncFn } from "react-use";

export default function App() {
  const [state, getData] = useAsyncFn(async () => {
    const response = await fetch("https://api.agify.io/?name=michael");
    const result = await response.json();
    return result;
  }, []);

  return (
    <div>
      <button onClick={() => getData()}>load</button>
      {(() => {
        if (state.loading) {
          return <div>Loading...</div>;
        }

        if (state.error) {
          return <div>Error</div>;
        }

        return <div>{JSON.stringify(state.value)}</div>;
      })()}
    </div>
  );
}

We pass in the same promise as we did with useAsync .

It returns the state like useAsync .

In addition, it returns the getData function to let us get the data.

The data is only retrieved if we call it.

Conclusion

The react-use library provides us with hooks to animate numbers, manually update a component, and run promises cleanly.

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 *