Categories
React Hooks

Top React Hooks — Refs, Redux, and Async

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.

reactive-react-redux

The reactive-react-redux library is an alternative library to React-Redux for using Redux stores in our React app.

To use it, we install it by running:

npm install reactive-react-redux

Then we can use it by writing:

import React from "react";
import { createStore } from "redux";
import { Provider, useDispatch, useTrackedState } from "reactive-react-redux";

const initialState = {
  count: 0
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "setText":
      return { ...state, text: action.text };
    default:
      return state;
  }
};

const store = createStore(reducer);

const Counter = () => {
  const state = useTrackedState();
  const dispatch = useDispatch();
  return (
    <div>
      <span>Count: {state.count}</span>
      <button type="button" onClick={() => dispatch({ type: "increment" })}>
        increment
      </button>
      <button type="button" onClick={() => dispatch({ type: "decrement" })}>
        decrement
      </button>
    </div>
  );
};

export default function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

We have our initialState constant with the initial state.

Our reducer is a Redux reducer.

The store is created with the createStore function from Redux to create our store from the reducer .

In the Counter component, we use the useTrackedState hook to get the state.

And we use the useDispatch hook to get the dispatch function to let us dispatch our action to the reducer.

Then in App , we use the Provider with the store prop set to our store to let us use it as a data store.

Provider , useTrackedState , and useDispatch are from reactive-react-redux.

We can also select values from a state and do more.

React-async-hook

React-async-hook is a library to help us make API calls easier.

To install it, we run;

yarn add react-async-hook

or:

npm install react-async-hook --save

Then we can use it by writing:

import React from "react";
import { useAsync } from "react-async-hook";

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

export default function App() {
  const person = useAsync(fetchName, ["michael"]);
  return (
    <div>
      {person.loading && <div>Loading</div>}
      {person.error && <div>Error</div>}
      {person.result && (
        <div>
          <div>{JSON.stringify(person.result)}</div>
        </div>
      )}
    </div>
  );
}

We created the fetchName function to get our data.

Then we use the useAsync hook with it and the value to pass into the parameter to make the API call.

Then person has the loading , error , and result properties.

loading indicates whether the data is loading.

error indicates the error state.

result has the response body.

react-context-refs

The react-context-refs library lets us get React refs via a context.

We can install it by running:

npm i react-context-refs

Then we can use it by writing:

import React from "react";
import { useContextRef } from "react-context-refs";

const Input = ({ value, onChange, hasError }) => {
  const setRef = useContextRef({ hasError });

  return (
    <input
      style={hasError ? { backgroundColor: "orange" } : {}}
      ref={setRef}
      value={value}
      onChange={onChange}
    />
  );
};

export default function App() {
  const [val, setVal] = React.useState("");

  return (
    <div>
      <Input value={val} onChange={e => setVal(e.target.value)} hasError />
    </div>
  );
}

We pass in the hasError value to the useContextRef hook so that we can pass the returned value to the ref.

Conclusion

reactive-react-redux is an alternative for React-Redux.

React-async-hook lets us get data asynchronously.

react-context-refs lets us pass things to the ref via a context.

Categories
React Hooks

Top React Hooks — Network, Dimensions, and Scroll

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.

@rehooks/network-status

The @rehooks/network-status hook lets us get the network status in our React app.

To use it, we run:

yarn add @rehooks/network-status

Then we can use the useNetworkStatus hook to get the network information:

import React from "react";
import useNetworkStatus from "@rehooks/network-status";

export default function App() {
  const connection = useNetworkStatus();
  return (
    <div>
      <div>downlink: {connection.downlink}</div>
      <div>effectiveType: {connection.effectiveType}</div>
      <div>rtt: {connection.rtt}</div>
      <div>saveData: {connection.saveData ? "yes" : "no"}</div>
    </div>
  );
}

downlink has the upload speed.

effectiveType hs the connection type.

rtt is the round trip delay, which is the length of time it takes for a single to be sent plus the length of time it takes for the signal to be acknowledged.

@rehooks/online-status

@rehooks/online-status is a package to get the online status of an app.

It listens to online or offline events to get the status.

To install it, we can run:

yarn add @rehooks/online-status

Then we can use it by writing:

import React from "react";
import useOnlineStatus from "@rehooks/online-status";

export default function App() {
  const onlineStatus = useOnlineStatus();
  return (
    <div>
      <h1>{onlineStatus ? "Online" : "Offline"}</h1>
    </div>
  );
}

We can use the useOnlineStatus hook to get the online status of our app.

@rehooks/window-scroll-position

We can use the @rehooks/window-scroll-position hook to watch the scroll position in our app.

To install the package, we run:

yarn add @rehooks/window-scroll-position

Then we can use the package buy writing:

import React from "react";
import useWindowScrollPosition from "@rehooks/window-scroll-position";

export default function App() {
  const options = {
    throttle: 100
  };
  let position = useWindowScrollPosition(options);
  return (
    <>
      <div style={{ position: "fixed" }}>{JSON.stringify(position)}</div>
      {Array(1000)
        .fill()
        .map((_, i) => (
          <p>{i}</p>
        ))}
    </>
  );
}

We use the useWindowScrollPosition hook to watch for scroll position.

We also pass in an option to throttle the position watching.

Then when we scroll, we’ll see the x and y properties of position change.

@rehooks/window-size

We can use the @rehooks/window-size package to watch for window size changes.

To install it, we run:

yarn add @rehooks/window-size

Then we can use it by writing:

import React from "react";
import useWindowSize from "@rehooks/window-size";

export default function App() {
  let windowSize = useWindowSize();

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

We then use the useWindowSize hook to get the window dimensions.

innerHeight has the interior height with the horizontal scroll bar’s height in pixels.

innerWidth has the interior width of the window with the vertical scrollbar in pixels.

outerHeight has the height of the whole browser window in pixels.

outerHeight has the width of the whole browser window in pixels.

They both include sidebars and other borders.

Conclusion

We can get network status, scroll position, and window size with various hooks.

Categories
React Hooks

Top React Hooks — Input Handling and Utilities

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.

Melting Pot

Melting Pot has a bunch of hooks that we can use in our React app.

It’s a utility library with many hooks.

To install it, we run:

npm install @withvoid/melting-pot --save

or:

yarn add @withvoid/melting-pot

Then we can use it by writing:

import React from "react";
import { useActive } from "@withvoid/melting-pot";

export default function App() {
  const { active, bind } = useActive();

  const styles = {
    emphasis: {
      backgroundColor: active ? "yellow" : "red",
      color: active ? "black" : "white",
      padding: 5,
      width: 55,
      textAlign: "center"
    }
  };

  return (
    <div {...bind}>
      <span style={styles.emphasis}>{active ? "red" : "white"}</span>
      <p>{active.toString()}</p>
    </div>
  );
}

We spread the bind object to the outer div to let us watch whether the items inside are active or not.

Now when we click it, we get the styles in the emphasis property displayed.

The active state changes when we click in and out of the outer div.

It’s active when we click inside the outer div.

It also provides the useDidMount hook as a replacement of the componentDidMount method in React.

We can use it by writing:

import React from "react";
import { useDidMount } from "@withvoid/melting-pot";

export default function App() {
  useDidMount(() => {
    console.log("hello world");
  });

  return <div />;
}

We just put whatever we want to run in the useDidMount callback to run it.

The useFormField hook lets us handle form values with ease.

For instance, we can write:

import React from "react";
import { useFormField } from "@withvoid/melting-pot";

export default function App() {
  const form = {
    name: useFormField(),
    age: useFormField()
  };

  const onSubmit = event => {
    event.preventDefault();
    if (!onValidate()) {
      return;
    }
    alert("Success");
    onReset();
  };

  const onReset = () => Object.values(form).map(({ reset }) => reset());

  const onValidate = () => {
    let isValid = true;
    Object.values(form).map(({ isEmpty, validate }) => {
      validate();
      if (isEmpty) {
        isValid = false;
      }
    });
    return isValid;
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <div>
          <label htmlFor="name">Name</label>
          <input id="name" {...form.name.bind} placeholder="name" />
          {form.name.isValid && <p>Name is required*</p>}
        </div>
        <div>
          <label htmlFor="age">Age</label>
          <input id="age" {...form.age.bind} type="number" placeholder="age" />
          {form.age.isValid && <p>Age is required*</p>}
        </div>
        <div>
          <button type="submit">Submit</button>
          <button type="button" onClick={onReset}>
            Reset
          </button>
        </div>
      </form>
    </div>
  );
}

to create a form with the name and age fields.

We pass everything in the form.name.bind and form.age.bind properties into the input to let us handle the form values.

Then we can use the isValid property of each field to check or validity.

The onReset function gets all the form fields and call reset on them.

There’s also a validate method in each form field to validate them.

isEmpty check whether it’s empty or not.

These are all provided by the useFormField hook.

Conclusion

The Melting Pot library lets us do many things that we would otherwise have to write ourselves.

Categories
React Hooks

Top React Hooks — Hover, Toggles, and Titles

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.

Melting Pot

Melting Pot has a bunch of hooks that we can use in our React app.

It’s a utility library with many hooks.

To install it, we run:

npm install @withvoid/melting-pot --save

or:

yarn add @withvoid/melting-pot

We can then use the useHover hook to watch for the hovering on an element.

To use it, we write:

import React from "react";
import { useHover } from "@withvoid/melting-pot";

export default function App() {
  const { hover, bind } = useHover();
  const styles = {
    emphasis: {
      display: "inline-block",
      backgroundColor: "red",
      color: "white",
      padding: 5,
      width: 55,
      textAlign: "center"
    }
  };

  return (
    <div {...bind}>
      <p>Hover me</p>
      <p>
        Status: <span style={styles.emphasis}>{String(hover)}</span>
      </p>
    </div>
  );
}

We pass the bind object to the div so we can watch everything inside the div when they’re hovered.

Then we can get the hover state with the hover value returned by useHover .

The useKeyPress hook lets us watch for specific key presses.

To use it, we can write:

import React from "react";
import { useKeyPress } from "@withvoid/melting-pot";

export default function App() {
  const [isKeyPressed, key] = useKeyPress("a");

  return (
    <p>
      {isKeyPressed && "a is pressed"} {key}
    </p>
  );
}

We use the useKeyPress hook to get the keypress.

The argument is the key that’s pressed.

Then we can get the pressed state with the isKeyPress state.

key has the key that’s being watched.

The useOnlineStatus hook lets us get the online status of our app.

To use it, we write:

import React from "react";
import { useOnlineStatus } from "@withvoid/melting-pot";

export default function App() {
  const { online } = useOnlineStatus();
  return (
    <div>
      <p>{online ? "You Are Online" : "You Are Offline"}</p>
    </div>
  );
}

Then we can use the useOnlineStatus hook to get the online property that has the status.

The useTitle hook lets us set the title of our page.

For example, we can use it by writing:

import React from "react";
import { useTitle } from "@withvoid/melting-pot";

export default function App() {
  const [count, setCount] = React.useState(1);
  useTitle(count);
  const onChange = value => {
    setCount(count => count + value);
  };
  const onIncrement = () => onChange(1);
  const onDecrement = () => onChange(-1);

  return (
    <div>
      <section>
        <button type="button" onClick={onIncrement}>
          +
        </button>
        <p>Count {count}</p>
        <button type="button" onClick={onDecrement}>
          -
        </button>
      </section>
    </div>
  );
}

We get use the useTitle hook to set the title by the count.

The count is updated when we click the buttons.

So the latest value of it would be used to set the title.

The useToggle hook lets us watch for the toggling of a value.

For example, we can write:

import React from "react";
import { useToggle } from "@withvoid/melting-pot";

export default function App() {
  const { on, onToggle } = useToggle();

  return (
    <div>
      <button onClick={onToggle}>{on ? "On" : "Off"}</button>
    </div>
  );
}

to add the useToggle hook.

It returns an object with the on state that has the toggle state.

And the onToggle function lets us toggle the on state.

Conclusion

We can use the Melting Pot library to do many things including watching network state, setting titles, watching for hovering, and toggling states.

Categories
React Hooks

Top React Hooks — Github and States

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.

@d2k/react-github

@d2k/react-github is a series of React hooks that let us get data from Github.

To install it, we run:

npm i @d2k/react-github --save

Then we can use the useLatestRelease hook by writing:

import React from "react";
import { useLatestRelease } from "@d2k/react-github";

export default function App() {
  const { release, loading, error } = useLatestRelease("facebook", "react");

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

We get the latest errors by using the useLatestRelease hook with the user and repo name.

Then release has an object with the release data.

loading and error have the loading and error states.

We can use the useTaggedRelease hook to get a tagged release from our app.

To use it, we write:

import React from "react";
import { useTaggedRelease } from "@d2k/react-github";

export default function App() {
  const { release, loading, error } = useTaggedRelease(
    "facebook",
    "react",
    "v16.8.4"
  );
  return (
    <>
      <div>{JSON.stringify(release)}</div>
    </>
  );
}

It also has the useForks hook to get the forks of a repo.

The first argument is the user.

The 2nd argument is the repo.

The 3rd is the tag version.

For instance, we can write:

import React from "react";
import { useForks } from "@d2k/react-github";

export default function App() {
  const { forks, loading, error } = useForks("facebook", "react");

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

to get the forks of React.

@d2k/react-localstorage

@d2k/react-localstorage is a package with hooks to manipulating local storage.

To use it, we run:

npm i @d2k/react-localstorage --save

to install it.

Then we can use it by writing:

import React from "react";
import useLocalStorage from "@d2k/react-localstorage";

export default function App() {
  const [firstName, setFirstName, removeFirstName] =   useLocalStorage(
    "firstName",
    "mary"
  );
  const [lastName, setLastName, removeLastName] = useLocalStorage(
    "lastName",
    "smith"
  );

  return (
    <>
      <div>
        {firstName && lastName && (
          <p>
            Hello {firstName} {lastName}
          </p>
        )}
      </div>
    </>
  );
}

We used the useLocalStorage hook which returns the current value, a function to update the item with the given key, and remove the item with the given key in this order.

The key is the first argument of the hook.

The default value is the 2nd argument.

Then we can use them to update our local storage instead of manipulating it directly.

Hookstate

The Hookstate package lets us manage state globally in our app.

It can be used as an alternative to state management solutions like Redux or Mobx.

To install it, we run:

npm install --save @hookstate/core

or:

yarn add @hookstate/core

to install it.

Then we can use the hooks it comes with by writing:

import React from "react";
import { createState, useState } from "@hookstate/core";
const globalState = createState(0);

export default function App() {
  const state = useState(globalState);
  return (
    <>
      <p>Counter value: {state.get()}</p>
      <button onClick={() => state.set(p => p + 1)}>Increment</button>
    </>
  );
}

We use the createState function to create a global state.

Then we can pass that into the Hookstate’s useState hook so we can do stuff to it.

We call get to get the current state.

And we call set to set the new state.

Conclusion

There’re useful hooks for getting data from Github and managing local storage and app state.