Categories
React Hooks

Top React Hooks — Fetch and State Helpers

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-fetch-hook

The react-fetch-hook lets us fetch data from an API with a hook.

Its size is small and Flow and TypeScript types are included.

To install it, we can run:

yarn add react-fetch-hook

or:

npm i react-fetch-hook --save

Then we can use it by writing:

import React from "react";
import useFetch from "react-fetch-hook";

export default function App() {
  const { isLoading, data } = useFetch("https://api.agify.io/?name=michael");

  return isLoading ? <div>Loading...</div> : <>{JSON.stringify(data)}</>;
}

We use the useFetch hook with the URL of the API endpoint we want to get data from.

The isLoading has the loading state and data has the data.

It supports error handling and do multiple requests.

We can also format our data in a custom format.

react-hanger

The react-hanger library comes with various hooks we can use to do various things.

To install it, we run:

yarn add react-hanger

We can use the useInput hook to do automatic form value binding.

For instance, we can write:

import React from "react";
import { useInput } from "react-hanger";

export default function App() {
  const newTodo = useInput("");

  return (
    <>
      <input type="text" value={newTodo.value} onChange={newTodo.onChange} />
      <p>{newTodo.value}</p>
    </>
  );
}

The useInput hook returns an object which has the value and onChange properties that we can pass into the respective props.

The useBoolean lets us toggle the value of a boolean easily.

For instance, we can write:

import React from "react";
import { useBoolean } from "react-hanger";

export default function App() {
  const showCounter = useBoolean(true);

  return (
    <>
      <button onClick={showCounter.toggle}>toggle</button>
      <p>{showCounter.value.toString()}</p>
    </>
  );
}

The useNumber hook lets us set a number as long as it’s within a range.

For instance, we can write:

import React from "react";
import { useNumber } from "react-hanger";

export default function App() {
  const limitedNumber = useNumber(3, { lowerLimit: 0, upperLimit: 5 });

  return (
    <>
      <button onClick={() => limitedNumber.increase()}> increase </button>
      <button onClick={() => limitedNumber.decrease()}> decrease </button>
      <p>{limitedNumber.value}</p>
    </>
  );
}

We have the useNumber hook with an object with the lowerLimit and upperLimit properties.

Then we can use the increase and decrease methods to change the value property of limitedNumber .

We can’t set a number beyond the given range with it.

We can also add the loop option and set it to true so that the number will loop when it reaches the limits.

If we remove the object in the 2nd argument of the hook, then the number can be set to any value:

import React from "react";
import { useNumber } from "react-hanger";

export default function App() {
  const limitedNumber = useNumber(3);

  return (
    <>
      <button onClick={() => limitedNumber.increase()}> increase </button>
      <button onClick={() => limitedNumber.decrease()}> decrease </button>
      <p>{limitedNumber.value}</p>
    </>
  );
}

Conclusion

react-fetch-hook lets us fetch data from endpoints without hassle.

Also, we can use the react-hanger hook which various state helpers.

Categories
React Hooks

Top React Hooks — Cookies, Debounce, and Clipboard

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 Recipes

React Recipes comes with many hooks that we can use to do various things.

We can use the useCopyClipboard hook to let us copy any string to the clipboard.

For instance, we can write:

import React from "react";
import { useCopyClipboard } from "react-recipes";

export default function App() {
  const [isCopied, setIsCopied] = useCopyClipboard();

  const copy = () => {
    setIsCopied("copy string");
  };

  return (
    <button onClick={copy} type="button">
      {isCopied ? "Copied" : "Copy"}
    </button>
  );
}

to create a button to copy a string to the clipboard.

The useCopyClipboard hook returns an array with the isCopied and setIsCopied variables.

isCopied indicates that the string is copied to the clipboard if it’s true .

setIsCopied copies the string to the clipboard.

The useDarkMode hook lets us toggle on and off dark mode.

The setting will be saved in local storage.

For instance, we can write:

import React from "react";
import { useDarkMode } from "react-recipes";

export default function App() {
  const [darkMode, setDarkMode] = useDarkMode();

  return (
    <div>
      <button onClick={() => setDarkMode(!darkMode)}>toggle dark mode</button>
      <p>{darkMode.toString()}</p>
    </div>
  );
}

The setDarkMode function sets whether dark mode is on or not.

darkMode has the toggle state of dark mode.

The setting would be saved as an entry with the key dark-mode-enabled in local storage.

It doesn’t come with any styles, so we’ve to set the dark mode styles ourselves.

useDebounce is a hook that lets us denounce any fast-changing value.

For instance, we can use it by writing:

import React from "react";
import { useDebounce } from "react-recipes";

export default function App() {
  const [searchTerm, setSearchTerm] = React.useState("");
  const [result, setResult] = React.useState({});

  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  const search = async () => {
    const res = await fetch(`https://api.agify.io/?name=${debouncedSearchTerm}`);
    const data = await res.json();
    setResult(data);
  };

  React.useEffect(() => {
    if (debouncedSearchTerm) {
      search();
    }
  }, [debouncedSearchTerm]);

  return (
    <div>
      <input value={searchTerm} onChange={e => setSearchTerm(e.target.value)} />
      <p>{JSON.stringify(result)}</p>
    </div>
  );
}

We use the useDebounce hook with the searchTerm state.

The 2nd argument is the delay to set the debouncedSearchTerm value in milliseconds.

Then we pass that into the array in the 2nd argument of useEffect to watch its value.

It’ll run the search function to get the data if debouncedSearchTerm is set.

The useDimensions hook let us get the dimension of any element.

To use it, we can write:

import React from "react";
import { useDimensions } from "react-recipes";

export default function App() {
  const [wrapperRef, dimensions] = useDimensions();

  return (
    <div ref={wrapperRef}>
      height: {dimensions.height}
      width: {dimensions.width}
    </div>
  );
}

The hook returns the wrapperRef that we pass as the value of the ref prop of the element that we want to watch the size of.

dimensions has the dimensions of the div that we passed the ref to.

Then as we change the size of the viewport, we’ll see the dimensions update.

Conclusion

React Recipes has hooks for rebounding, copying to clipboard, watching element sizes, and manipulating cookies.

Categories
React Hooks

Top React Hooks — Clipboard, APIs, and Forms

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-clipboard

The react-use-clipboard library provides us with copy to clipboard functionality.

To install it, we run:

npm install react-use-clipboard --save-exact

or

yarn add react-use-clipboard --exact

Then we can use it by writing:

import React from "react";
import useClipboard from "react-use-clipboard";

export default function App() {
  const [isCopied, setCopied] = useClipboard("hello world");

  return (
    <button onClick={setCopied}>{isCopied ? "copied" : "not copied"}</button>
  );
}

We use the useClipboard hook with a string argument to let us copy it to the clipboard.

isCopied is a boolean to indicate whether it’s copied or not.

setCopied lets us copy the text to the clipboard.

We can reset the isCopied state after a period of time.

To do that, we can pass an object into the 2nd argument with the successDuration property:

import React from "react";
import useClipboard from "react-use-clipboard";

export default function App() {
  const [isCopied, setCopied] = useClipboard("hello world", {
    successDuration: 1000
  });

  return (
    <button onClick={setCopied}>{isCopied ? "copied" : "not copied"}</button>
  );
}

The number is in milliseconds.

react-use-data-loader

The react-use-data-loader library lets us load data with logic outside our component.

To install it, we run:

npm install --save react-use-data-loader

or:

yarn add react-use-data-loader

Then we can use it by writing;

import React from "react";
import { useDataLoader } from "react-use-data-loader";

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

export default function App() {
  const { data, error, loading, retry } = useDataLoader(getData, "michael");

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

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

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

We have the getData function which returns a promise with the response body.

Then we can pass that into the useDataLoader hook so that we can get the data we want with it.

The 2nd argument of the hook is passed to the parameter of the getData function.

It returns the data , error , loading and retry properties.

data has the resolved data.

error has the errors object.

loading has the loading state.

react-use-form-state

The react-use-form-state library lets us create forms without hassle.

To install it, we run:

npm install --save react-use-form-state

Then we can use it by writing:

import React from "react";
import { useFormState } from "react-use-form-state";

export default function App() {
  const [formState, { text, email, password, radio }] = useFormState();

  function handleSubmit(e) {
    e.preventDefault();
    console.log(formState.values);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input {...text("name")} placeholder="name" />
      <input {...email("email")} required placeholder="email" />
      <input
        {...password("password")}
        required
        minLength="8"
        placeholder="password"
      />
      <br />
      <input {...radio("plan", "free")} /> free
      <input {...radio("plan", "premium")} /> premium
      <br />
      <input type="submit" />
    </form>
  );
}

We use the useFormStare hook to create our form.

It returns an object with the formState with the form’s state, including the values, pristine, dirty, etc.

text , email , password , and radio are functions that we can call to add the type of input with the given name.

It returns an object with the value and form handler, which we can use in our input.

The first argument of these functions are the value of the name attribute.

The 2nd argument is the value of the value attribute.

Then we can get the form values with the formState.values .

Conclusion

react-use-clipboard lets us copy data to the clipboard.

react-use-data-loader lets us load data from APIs with ease.

react-use-form-state lets us create forms without the usual hard work.

Categories
React Hooks

Top React Hooks — Calendar, Form, and API

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-uniformed

The react-uniformed package lets us create forms with ease.

To install it, we run:

npm install --save react-uniformed

or:

yarn add react-uniformed

to install it.

Then we can use it by writing:

import React from "react";
import { useForm, useSettersAsEventHandler } from "react-uniformed";

export default function App() {
  const { setValue, values, submit } = useForm({
    onSubmit: data => console.log(data)
  });

  const handleChange = useSettersAsEventHandler(setValue);

  return (
    <>
      <form onSubmit={submit}>
        <label>Name</label>
        <input name="name" value={values.name} onChange={handleChange} />

<button>Submit</button>
      </form>
    </>
  );
}

We created a basic form with the form element.

The useForm hook takes an object with the onSubmit method.

data has the data we submit.

The object it returns has the setValue , values , and submit properties.

setValue is used with the useSettersAsEventHandler hook to get the change handler function.

The submit function is passed into the submit prop.

React Use API

React Use API is another library that lets us make HTTP requests cleanly.

To use it, we run:

npm i react-use-api axios

or:

yarn add react-use-api axios

to install it.

Then we can use it by writing:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { ApiProvider } from "react-use-api";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <ApiProvider>
    <App />
  </ApiProvider>,
  rootElement
);

App.js

import React from "react";
import useApi from "react-use-api";

export default function App() {
  const [data, { loading, error }, request] = useApi({
    url: "https://api.agify.io?name=michael"
  });

  return (
    <>
      {loading && <div>Loading...</div>}
      {error && <div>{error.response.data.errMsg}</div>}
      {data && <>{JSON.stringify(data)}</>}
    </>
  );
}

We import the ApiProvider that wraps around the App component.

Then we can use the useApi hook by passing in an object with the url to the API.

That returns the data , loading , error and request objects.

data has the response body.

loading has the request loading state.

error has the error object.

request is a function that lets us make the request again.

react-use-calendar

The react-use-calendar library is a library that lets us add a calendar to our app.

To use it, we run:

npm install react-use-calendar --save

to install it.

Then we write:

import React from "react";
import useCalendar from "react-use-calendar";

export default function App() {
  const [state, actions] = useCalendar(null, {
    events: [
      {
        startDate: new Date(2020, 8, 27),
        endDate: new Date(2020, 8, 27),
        note: "meeting"
      },
      {
        startDate: new Date(2020, 8, 22),
        endDate: new Date(2020, 8, 25),
        note: "vacation"
      }
    ]
  });

  return (
    <table>
      <thead>
        <tr>
          <td colSpan={5} style={{ textAlign: "center" }}>
            <strong>
              {state.month} - {state.year}
            </strong>
          </td>
          <td colSpan={2} style={{ textAlign: "right" }}>
            <button onClick={() => actions.getPrevMonth()}>&lt;</button>
            <button onClick={() => actions.getNextMonth()}>&gt;</button>
          </td>
        </tr>
        <tr>
          {state.days.map(day => (
            <th key={day}>{day}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {state.weeks.map((week, index) => (
          <tr key={index}>
            {week.map(day => (
              <td
                key={day.dayOfMonth}
                style={{
                  textAlign: "center",
                  backgroundColor: day.isToday ? "orange" : "#fff"
                }}
              >
                {day.dayOfMonth}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

to use it.

We display the calendar with today’s date displayed in orange.

events is an array with calendar events.

We’ve to render the calendar and events ourselves with our own table.

Conclusion

react-uniformed lets us create a simple form.

React Use API lets us make API requests.

react-use-calendar is a hook that lets us create a calendar.

Categories
React Hooks

Top React Hooks — Async and Window

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 Recipes

React Recipes comes with many hooks that we can use to do various things.

The useWindowSize hook lets watch the size of the window as it changes.

For instance, we can write:

import React from "react";
import { useWindowSize } from "react-recipes";

export default function App() {
  const { width, height } = useWindowSize();

  return (
    <div>
      {width}x{height}
    </div>
  );
}

We call the useWindowSize hook to return the width and height properties.

They’re the width and height of the window.

We can also pass in the initial width and height, which are useful for server-side rendered apps.

It comes with many other useful hooks to make our lives easier.

React Request Hook

The React Request Hook library lets us make requests with ease.

To install it, we run:

yarn add react-request-hook axios

or:

npm install --save react-request-hook axios

Then we can use it by writing:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { RequestProvider } from "react-request-hook";
import axios from "axios";
import App from "./App";

const axiosInstance = axios.create({
  baseURL: "https://api.agify.io/"
});

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <RequestProvider value={axiosInstance}>
      <App />
    </RequestProvider>
  </React.StrictMode>,
  rootElement
);

App.js

import React from "react";
import { useResource } from "react-request-hook";

export default function App() {
  const [name, getName] = useResource(name => ({
    url: `/?name=${name}`,
    method: "get"
  }));

  React.useEffect(() => {
    getName("michael");
  }, []);

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

In index.js , we create the Axios instance and pass it into the RequestProvider component.

The value prop takes the Axios instance.

Then we can use the useResource hook in App to get the data we want.

In the callback we pass in, we return the url and method .

The url is the path relative to the URL in the Axios instance.

method is the request method.

It returns an array with the result and the function to get the result.

name has the response body.

And getName is a function that takes the same parameter as the useResource callback to get the data.

Then we can call getName to get the data.

It also provides us with other ways to make requests.

React-RocketJump

React-RocketJump is another library that lets us commit async side effects in our React app.

To use it, we install it by running:

yarn add react-rocketjump

Then we can use it by writing:

import React from "react";
import { rj, useRunRj } from "react-rocketjump";

const NameState = rj({
  effect: () => fetch(`https://api.agify.io/?name=michael`).then(r => r.json())
});

export default function App() {
  const [{ data: name, pending, error }] = useRunRj(NameState);

  return (
    <>
      {error && <div>Got some troubles</div>}
      {pending && <div>Wait...</div>}
      {JSON.stringify(name)}
    </>
  );
}

We create our side effect with the rj function.

The object has the effect method which returns a promise with the data.

Then in App , we use the useRunRj hook to get the data.

We pass in NameState as the argument of the hook.

Then it returns an array with an object that has the data , pending , and error properties.

data has the response body.

pending has the pending status.

error has the error.

Conclusion

React Recipes, React Request Hook, and React-RocketJump are all useful libraries that give us various hooks to do what we want.