Categories
React Hooks

Top React Hooks — Scroll and Breakpoints

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.

The useScrolling hook lets us keep track of whether the user is scrolling an element or not.

To use it, we can write:

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

export default function App() {
  const scrollRef = React.useRef(null);
  const scrolling = useScrolling(scrollRef);

  return (
    <div ref={scrollRef} style={{ overflow: "scroll", height: 300 }}>
      <div style={{ position: "fixed" }}>
        {scrolling ? "Scrolling" : "Not scrolling"}
      </div>
      {Array(1000)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
}

We create the ref that we pass into the element that we want to watch the scrolling for.

Also, we pass the ref to the element to the useScrolling hook.

The hook returns the scrolling state of the element.

The useScrollbarWidth hook returns the browser’s scrollbar width.

It’ll return undefiuned until the DOM is ready.

For instance, we can write:

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

export default function App() {
  const sbw = useScrollbarWidth();

  return (
    <div>
      {sbw === undefined
        ? `DOM is not ready yet`
        : `scrollbar width is ${sbw}px`}
    </div>
  );
}

We have the useScrollbarWidth hook which returns the scroll bar width.

The useWindowSize hook returns the dimensions of the browser window.

For instance, we can write:

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

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

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

We called the useWindowSize hook to get the width and height of the window.

We can use the useMeasure hook to get the dimensions of an HTML element.

It uses the resize observer API to do so.

For example, we can write:

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

export default function App() {
  const [ref, { x, y, width, height, top, right, bottom, left }] = useMeasure();

  return (
    <div ref={ref}>
      <div>x: {x}</div>
      <div>y: {y}</div>
      <div>width: {width}</div>
      <div>height: {height}</div>
      <div>top: {top}</div>
      <div>right: {right}</div>
      <div>bottom: {bottom}</div>
      <div>left: {left}</div>
    </div>
  );
}

x and y are the x and y coordinates of the top left corner of the element.

width and height are their width and height.

top , right , bottom , and left are the position values of the element.

The createBreakpoint function creates the useBreakpoint hook lets us detect screen width breakpoints.

For instance, we can write:

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

const useBreakpoint = createBreakpoint();

export default function App() {
  const breakpoint = useBreakpoint();

  if (breakpoint === "laptopL") return <div> very big Laptop </div>;
  else if (breakpoint === "laptop") return <div> Laptop</div>;
  else if (breakpoint === "tablet") return <div>Tablet</div>;
  else return <div>Too small</div>;
}

We have the useBreakpoint hook which returns the breakpoint that matches the screen size.

Also, we can change the breakpoints by passing in an object to createBreakpoint :

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

const useBreakpoint = createBreakpoint({ XL: 1200, L: 700, S: 350 });

export default function App() {
  const breakpoint = useBreakpoint();

  if (breakpoint === "XL") return <div>XL</div>;
  else if (breakpoint === "L") return <div>L</div>;
  else if (breakpoint === "S") return <div>S</div>;
  else return <div>too small</div>;
}

We pass in an object with the breakpoint names as the keys and the widths as the values.

Then we use useBreakpoint the same way.

Conclusion

The react-use package has hooks to detect widths and detect scrolling.

Categories
React Hooks

Top React Hooks — Promises, Tweens, and Manual Update

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.

Categories
React Hooks

Top React Hooks — Permissions, Titles, Lifecycle

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.

useTitle

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

We can use it by writing:

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

export default function App() {
  useTitle("Hello world!");

  return <div className="App" />;
}

We pass the string to the hook to set the title.

usePermission

We can use the usePermission hook to query the permission status of browser APIs.

For instance, we can write:

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

export default function App() {
  const state = usePermission({ name: "geolocation" });

  return <pre>{JSON.stringify(state, null, 2)}</pre>;
}

to get the location given the value of the name property of the object we pass into the hook.

useEffectOnce

The useEffectOnce let us run a side effect only once.

For instance, we can write:

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

export default function App() {
  useEffectOnce(() => {
    console.log("running");

    return () => {
      console.log("cleaning up");
    };
  });
  return <div />;
}

We have the useEffectOnce hook with a callback that runs when the component mounts.

The function that’s returned is run when the component unmounts.

This is handy for running any cleanup code.

useEvent

The useEvent hook lets us listen for events in our code.

For instance,e we can write:

import React from "react";
import { useList, useEvent } from "react-use";

export default function App() {
  const [list, { push, clear }] = useList();

  const onKeyDown = React.useCallback(({ key }) => {
    if (key === "x") {
      clear();
    }
    push(key);
  }, []);

  useEvent("keydown", onKeyDown);

  return (
    <div>
      <pre>{JSON.stringify(list, null, 2)}</pre>
    </div>
  );
}

We listen to the keydown event by passing in a callback.

The callback takes an event object with the key property for the key.

The useList hook returns the list which has the list.

push lets us push to list .

clear lets us clear the list .

If ‘x’ is pressed then the list is cleared.

Otherwise, we push the key that’s pressed to the list .

And we pass that into the 2nd argument of useEvent to run it on key down.

useLifecycles

The useLifecycles hook lets us pass in callback to run when the component mounts and unmounts.

We can use it by writing:

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

export default function App() {
  useLifecycles(() => console.log("mounted"), () => console.log("unmounted"));

  return <div />;
}

The useLifecycke hook takes 2 arguments.

The first is the callback that runs when the component mounts.

The 2nd is the callback that runs when the component unmounts.

Conclusion

The react-use library lets us create lifecycle methods, change the title of the page, and query for browser permissions.

Categories
React Hooks

Top React Hooks — Number Animation and Timers

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.

useSpring

The useSpring hook lets us update a single numeric value over time.

To use it, we’ve to install by rebound library by running:

npm i rebound

For instance, we can use it by writing:

import React from "react";
import useSpring from "react-use/lib/useSpring";

export default function App() {
  const [target, setTarget] = React.useState(50);
  const value = useSpring(target);

  return (
    <div>
      {value}
      <br />
      <button onClick={() => setTarget(0)}>Set 0</button>
      <button onClick={() => setTarget(200)}>Set 200</button>
    </div>
  );
}

We have the target which is a numeric state.

setTarget lets us set the target state.

useSpring lets us jump to the given value with an animation.

This works when we pass in target to the hook.

useTimeout

The useTimeout hook lets us re-render the component after a specified number of milliseconds.

For example, we can use it by writing:

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

export default function App() {
  const [isReady, cancel] = useTimeout(1000);

  return (
    <div>
      {isReady() ? "after reload" : `before reload`}
      <br />
      {isReady() === false ? <button onClick={cancel}>Cancel</button> : ""}
    </div>
  );
}

The useTimeout function takes a duration before reloading in milliseconds.

isReady is a function that determines if the component is ready to reload.

If it is, then it returns false .

cancel is a function that lets us cancel the reloading.

useTimeoutFn

The useTimeoutFn ook lets us run a function after a given delay in milliseconds.

It doesn’t re-render the component.

Canceling is automatic.

The timeout is reset on delay change.

The reset function will cancel the previous timeout.

Timeout won’t reset on function changes.

For example, we can use it by writing:

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

export default function App() {
  const [state, setState] = React.useState("before call");

function fn() {
    setState(`called at ${Date.now()}`);
  }

const [isReady, cancel, reset] = useTimeoutFn(fn, 5000);
  const cancelButtonClick = React.useCallback(() => {
    if (isReady() === false) {
      cancel();
      setState(`cancelled`);
    } else {
      reset();
      setState("before call");
    }
  }, []);

  const readyState = isReady();

  return (
    <div>
      <div>
        {readyState !== null ? "Function will be called" : "Timer cancelled"}
      </div>
      <button onClick={cancelButtonClick}>
        {readyState === false ? "cancel" : "restart"} timeout
      </button>
      <div>{state}</div>
    </div>
  );
}

We use the useTimeoutFn hook to create our timer to run a function after a given delay.

The delay is given in milliseconds in the 2nd argument.

We also created the cancelButtonClick function that uses the functions returned by useTimeoutFn .

cancel cancels the timer so the callback won’t run.

reset lets us reset the timer to start from the beginning.

isReady is a function that returns whether the callback is ready to run.

It’s ready if the callback hasn’t been called yet.

Conclusion

The react-use library comes with various useful hooks, including hooks that create timers and animate numbers.

Categories
React Hooks

Top React Hooks — Network, Long Press, and Scrolling

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.

The useNetwork hook lets us detect the network type.

To us it, we can write:

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

export default function App() {
  const state = useNetwork();

  return <pre>{JSON.stringify(state, null, 2)}</pre>;
}

We call the useNetwork hook to return the network state.

The returned object has the online , downlink , effectiveType and rtt properties.

online has the online status.

downlink has internet downlink.

effectiveType has the effective network type.

rtt has the round trip delay.

The useOrientation hook lets us track the screen orientation of the user’s device.

To use it, we write:

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

export default function App() {
  const state = useOrientation();

  return <pre>{JSON.stringify(state, null, 2)}</pre>;
}

We use the useOrientation hook to return an object with the orientation data.

Then object has the angle , which is the angle of the screen.

It also has the type property, which is the screen orientation.

The usePageLeave hook lets us run a callback when the mouse leaves the page.

For instance, we can write:

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

export default function App() {
  usePageLeave(() => console.log("left page"));

  return <></>;
}

The hook takes a callback that runs when our mouse leaves the page.

The useStartTyping hook lets us detect when we start typing.

It takes a callback that runs when we start typing.

For example, we can write:

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

export default function App() {
  useStartTyping(() => console.log("Started typing"));

  return null;
}

The useWindowScroll hook lets us rerender on window scroll.

For example, we can write:

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

export default function App() {
  const { x, y } = useWindowScroll();

  return (
    <div>
      <div style={{ position: "fixed" }}>
        x: {x} y: {y}
      </div>
      {Array(1000)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
}

We have the useWindowScroll hook that returns the x and y coordinates of the scrolling.

The useScroll hook lets us watch for the scrolling of an element.

To use it, we can write:

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

export default function App() {
  const scrollRef = React.useRef(null);
  const { x, y } = useScroll(scrollRef);

  return (
    <div ref={scrollRef} style={{ overflow: "scroll", height: 300 }}>
      <div style={{ position: "fixed" }}>
        x: {x} y: {y}
      </div>
      {Array(1000)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
}

We created a ref and pass that into the element that we want to watch the scrolling for.

We’ve to set the overflow style so that we scroll the element when there’s overflowing content.

Conclusion

The react-use package has hooks to listening to scrolling on the window and elements.

Also, we can watch for key presses.