Categories
React Hooks

Top React Hooks — Renders 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.

react-use

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

useMediatedState

We can use the useMediatedState hook is a hooks that works like useState , but we can run a callback to manipulate the state before returning it.

To use it, we can write:

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

const inputMediator = s => s.replace(/s+/g, "");

export default function App() {
  const [state, setState] = useMediatedState(inputMediator, "");

  return (
    <div>
      <input
        type="text"
        min="0"
        max="10"
        value={state}
        onChange={ev => {
          setState(ev.target.value);
        }}
      />
    </div>
  );
}

to use the useMediatedState hook to remove the spaces in the text we typed in before returning the state .

The first argument is the callback to manipulate the state and the 2nd is the initial value.

useFirstMountState

The useFirstMountState hook lets us check if the component is just mounted.

It’ll return true if it’s just mounted and false otherwise.

For instance, we can use it by writing:

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

export default function App() {
  const isFirstMount = useFirstMountState();

  return (
    <div>
      <span>{isFirstMount.toString()}</span>
    </div>
  );
}

It’ll show true if it’s first mounted and false otherwise.

It takes no arguments.

useRendersCount

We can use the useRendersCount hook to track the renders count including the first render.

For instance, we can write:

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

export default function App() {
  const update = useUpdate();
  const rendersCount = useRendersCount();
  return (
    <div>
      <span>render count: {rendersCount}</span>
      <br />
      <button onClick={update}>refresh</button>
    </div>
  );
}

We have a button that calls the update function returned by useUpdate to update our component.

It’ll cause a re-render so the rendersCount will increase by 1.

useGlobalState

The useGlobalState hook lets us create a global state that we can share between components.

For instance, we can write:

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

const useGlobalValue = createGlobalState(0);

const Increase = () => {
  const [value, setValue] = useGlobalValue();

  return <button onClick={() => setValue(value + 1)}>increase</button>;
};

const Decrease = () => {
  const [value, setValue] = useGlobalValue();

  return <button onClick={() => setValue(value - 1)}>decrease</button>;
};

export default function App() {
  const [value] = useGlobalValue();
  return (
    <div>
      <p>{value}</p>
      <Increase />
      <Decrease />
    </div>
  );
}

We called the createGlobalState hook with an initial value to return the useGlobalValue hook.

It returns an array with the value and setValue variables.

value has the state value and setValue has the function to set the value .

We use the useGlobalValue hook in all the components.

In Increase , we used it to increase the value .

In Decrease , we used it to decrease the value .

In App , we only used the hook to get the value .

Conclusion

The react-use library has hooks to get and set states in various ways.

We can also use it to get render count and state.

Categories
React Hooks

Top React Hooks — Portals and Redux

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.

useMiddleware

The react-usemiddleware hook lets us create a state with Redux middlewares.

To install it, we run:

npm install react-usemiddleware --save

or:

yarn add react-usemiddleware

Then we can use it by writing:

import React from "react";
import { createLogger } from "redux-logger";
import useMiddleware from "react-usemiddleware";

const logger = createLogger();
const middlewares = [logger];

const initState = {
  count: 0
};

const reducer = (state, action) => {
  switch (action.type) {
    case "INCREMENT":
      return { count: state.count + 1 };
    default:
      return state;
  }
};

export default function App() {
  const [state, dispatch] = useMiddleware(reducer, initState, middlewares);
  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "INCREMENT" })}>increment</button>
      <span>{state.count}</span>
    </div>
  );
}

We have the redux logger that we created with the createLogger function.

We also have the initState with the initial state.

And we created a reducer that’s the usual reducer format.

We pass in the reducer , initState , and middlewares in the useMiddleware hook.

It returns the state with the state from the Redux store and the dispatch function that lets us dispatch an action.

We have the state.count with our count state from the store.

react-useportal

The react-useportal package lets us create portals, which are elements that render outside their usual hierarchy.

To install it, we run:

yarn add react-useportal

or:

npm i -S react-useportal

Then we can use it by writing:

import React from "react";
import usePortal from "react-useportal";

export default function App() {
  const { Portal } = usePortal();

  return <Portal>hello world</Portal>;
}

We just return the Portal component by calling the usePortal hook.

Then we can pass in anything in there.

The items will be rendered in the body element.

We can also render the items inside in another element.

For instance, we can write:

import React from "react";
import usePortal from "react-useportal";

export default function App() {
  const { Portal } = usePortal({
    bindTo: document && document.getElementById("hello-world")
  });

  return <Portal>hello world</Portal>;
}

to render the items inside Portal in the element with ID hello-world .

We can also use states to render the portal dynamically.

For instance, we can write:

import React from "react";
import usePortal from "react-useportal";

export default function App() {
  const { openPortal, closePortal, isOpen, Portal } = usePortal();

  return (
    <>
      <button onClick={openPortal}>Open</button>
      {isOpen && (
        <Portal>
          <div>
            <button onClick={closePortal}>Close</button>
            <p>hello world</p>
          </div>
        </Portal>
      )}
    </>
  );
}

The usePortal hook returns an object with the variables.

The Portal is the portal.

isOpen checks whether the portal is attached or not.

openPortal is a function that set isOpen to true .

closePortal is a function that sets isOpen to false .

We can also press Esc to remove the portal.

This is handy for modals.

Conclusion

The useMiddleware hook lets us use Redux middlewares to our apps.

We can use react-useportal to add portals to our app.

Categories
React Hooks

Top React Hooks — Observables and Hooks

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 Hooks for RxJS

The React Hooks for RxJS library lets us use Rxjs observables in our React components.

To install it, we can run:

npm i --save rxjs-hooks

or:

yarn add rxjs-hooks

We can use it by writing:

import React from "react";
import { useObservable } from "rxjs-hooks";
import { interval } from "rxjs";
import { map } from "rxjs/operators";

export default function App() {
  const value = useObservable(() => interval(2000).pipe(map(val => val * 2)));

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
}

We use the interval observable with the useObservable hook.

It returns the value of the observable.

The pipe operator lets us modify the value generated from the interval observable.

It also comes with the useEventCallback hook to let us watch for event object changes.

For instance, we can write:

import React from "react";
import { useEventCallback } from "rxjs-hooks";
import { map } from "rxjs/operators";

export default function App() {
  const [clickCallback, [description, x, y]] = useEventCallback(
    event$ =>
      event$.pipe(
        map(event => [event.target.innerHTML, event.clientX, event.clientY])
      ),
    ["nothing", 0, 0]
  );

  return (
    <div className="App">
      <p>
        click position: {x}, {y}
      </p>
      <p>{description} was clicked.</p>
      <button onClick={clickCallback}>click foo</button>
      <button onClick={clickCallback}>click bar</button>
      <button onClick={clickCallback}>click baz</button>
    </div>
  );
}

We called the useEventCallback hook with a callback that takes th event$ observable.

It returns the piped results returned from the pipe operator.

map lets us return an object we can get the click event object properties from.

The hook returns an array with the clickCallback that we can use as click handlers.

The 2nd entry is the click event object.

The 3rd argument is an array with the initial values of the properties in the click event object.

Scroll Data Hook

The Scroll Data Hook library lets us return information about scroll speed, distance, direction, and more.

To use it, we can install it by running:

yarn add scroll-data-hook

Then we can use it by writing:

import React from "react";
import { useScrollData } from "scroll-data-hook";

export default function App() {
  const {
    scrolling,
    time,
    speed,
    direction,
    position,
    relativeDistance,
    totalDistance
  } = useScrollData({
    onScrollStart: () => {
      console.log("Started scrolling");
    },
    onScrollEnd: () => {
      console.log("Finished scrolling");
    }
  });

  return (
    <div>
      <div style={{ position: "fixed" }}>
        <p>{scrolling ? "Scrolling" : "Not scrolling"}</p>
        <p>Scrolling time: {time} milliseconds</p>
        <p>Horizontal speed: {speed.x} pixels per second</p>
        <p>Vertical speed: {speed.y} pixels per second</p>
        <p>
          Position: {position.x} {position.y}
        </p>
        <p>
          Direction: {direction.x} {direction.y}
        </p>
        <p>
          Relative distance: {relativeDistance.x}/{relativeDistance.y}
        </p>
        <p>
          Total distance: {totalDistance.x}/{totalDistance.y}
        </p>
      </div>
      <div>
        {Array(1000)
          .fill()
          .map((_, i) => (
            <p key={i}>{i}</p>
          ))}
      </div>
    </div>
  );
}

We call the useScrollData hook with the object that has a callback that runs when we scroll.

onScrollStart runs when we start scrolling.

onScrollEnd runs when we stop scrolling.

The hook returns an object with various properties.

scrolling is a boolean to indicate whether we’re scrolling.

time is how long we scrolled.

speed is the scrolling speed.

direction is the scrolling direction.

position is the scrolling position.

Conclusion

React Hooks for RxJS lets us use Rxjs observables in our React app.

Scroll Data Hook lets us watch for different kinds of scrolling data in our app.

Categories
React Hooks

Top React Hooks — Forms and Forward Refs

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.

useMethods

The useMethods hook is a simpler useReducer hook implementation.

It lets us cache states so it’s useful for using complex computations.

For instance, we can write:

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

const initialState = {
  count: 0
};

function countMethods(state) {
  return {
    reset() {
      return initialState;
    },
    increment() {
      return { ...state, count: state.count + 1 };
    },
    decrement() {
      return { ...state, count: state.count - 1 };
    }
  };
}

export default function App() {
  const [state, methods] = useMethods(countMethods, initialState);

  return (
    <>
      <p>{state.count}</p>
      <button onClick={methods.increment}>increment</button>
      <button onClick={methods.decrement}>decrement</button>
      <button onClick={methods.reset}>reset</button>
    </>
  );
}

We created the countMethods function with the methods we can use to manipulate our state .

It returns the state as we want to by returning an object with various methods.

reset returns the initial state.

increment returns a state with count increased by 1.

decrement returns a state with count decreased by 1.

We passed the countMethods function into the useMethods hook along with the initialState .

Then that returns the state and the methods object that has the methods returned by countMethods .

We then called them when we click the buttons.

useEnsuredForwardedRef

The useEnsuredForwardedRef hook letrs us forward refs to a child component.

For instance, we can write:

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

const Foo = React.forwardRef((props, ref) => {
  const ensuredForwardRef = useEnsuredForwardedRef(ref);

  React.useEffect(() => {
    console.log(ensuredForwardRef.current);
  }, []);

  return <div ref={ensuredForwardRef} />;
});

export default function App() {
  return (
    <>
      <Foo />
    </>
  );
}

to use the hook.

We just pass in a ref to the useEnsuredForwardRef hook and it’ll return ensuredForwardRef .

It’ll never be undefined , so we can use it as we do in the useEffect callback.

useFormless

React-useFormless is a simple library that lets us create forms with a simple hook.

We can install it by running:

yarn add react-useformless

or

npm install react-useformless

Then we can use it by writing:

import React from "react";
import useFormless from "react-useformless";

const options = {
  initialValues: {
    name: "",
    password: ""
  },
  validate: (name, value) => {
    const validators = {
      name: name => (name.length > 0 ? "" : "name is requred"),
      password: password => (password.length > 0 ? "" : "password is required")
    };

const errorFn = validators[name];
    return errorFn(value);
  },
  onError: (ev, { values, errors }) => {
    ev.preventDefault();
  },
  onSuccess: (ev, { values }) => {
    ev.preventDefault();
  },
  onSubmit: ev => {
    ev.preventDefault();
    console.log(ev);
  }
};

export default function App() {
  const { values, errors, inputProps, onSubmit } = useFormless(options);

 return (
    <section>
      <form onSubmit={onSubmit}>
        <div>
          <label htmlFor="name">name</label>
          <input
            id="name"
            type="text"
            {...inputProps("name")}
            value={values.name}
          />
          <p>{errors.name}</p>
        </div>
        <div>
          <label htmlFor="password">password</label>
          <input
            id="password"
            type="password"
            {...inputProps("password")}
            value={values.password}
          />
          <p>{errors.password}</p>
        </div>
        <input type="submit" value="Login" />
      </form>
    </section>
  );
}

We have the options object with the options.

initialValues has the initial values of the form.

validate is a function that returns an error object after validation.

The returned object should have the keys with the input names and values being the error message.

onError , onSuccess and onSubmit are handlers that are run when those events are emitted.

We pass in the whole object to the useFormless hook.

It returns an object with the variables we can use in our form.

inputProps pass in the input elements.

onSubmit is the submit handler.

errors has the error messages.

values has the input values for each field.

Conclusion

React-use is a versatile hooks library.

React-useFormless lets us create forms easily with our React app.

Categories
React Hooks

Top React Hooks — Data Types

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.

useToggle

The useToggle hook lets us create a boolean state that we can toggle with a function.

To use it, we can write:

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

export default function App() {
  const [on, toggle] = useToggle(true);

  return (
    <div>
      <div>{on.toString()}</div>
      <button onClick={toggle}>toggle</button>
      <button onClick={() => toggle(true)}>true</button>
      <button onClick={() => toggle(false)}>false</button>
    </div>
  );
}

useToggle takes an argument for the initial value of the toggle.

It returns the on state with the boolean.

And toggle lets us toggle the value or set on with a specific value.

useCounter

The useCounter hook lets us create a numeric state with functions to set or reset the value.

For instance, we can write:

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

export default function App() {
  const [val, { inc, dec, set, reset }] = useCounter(1);

  return (
    <div>
      <div>{val}</div>
      <button onClick={() => inc()}>Increment</button>
      <button onClick={() => dec()}>Decrement</button>
      <button onClick={() => reset()}>Reset</button>
      <button onClick={() => set(100)}>Set 100</button>
    </div>
  );
}

We call the useCounter hook to return an array with various things.

The argument is the initial value.

val has the current value of the number state.

inc is the function to increment val .

dec is the function to decrement val .

set is the function to set val to a specific value.

reset resets val to the initial value.

We can also set the maximum and minimum values that val can take.

For example, we can write:

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

export default function App() {
  const [val, { inc, dec, set, reset }] = useCounter(1, 10, 1);

  return (
    <div>
      <div>{val}</div>
      <button onClick={() => inc()}>Increment</button>
      <button onClick={() => dec()}>Decrement</button>
      <button onClick={() => reset()}>Reset</button>
      <button onClick={() => set(9)}>Set 9</button>
    </div>
  );
}

The 2nd argument of useCounter is the maximum value of val .

The 3rd argument is the minimum value of val that it can take.

useList

The useList hook lets us create a state from an array and manipulate it.

To use it, we can write:

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

export default function App() {
  const [
    list,
    {
      set,
      push,
      updateAt,
      insertAt,
      update,
      updateFirst,
      upsert,
      sort,
      filter,
      removeAt,
      clear,
      reset
    }
  ] = useList([1, 2, 3, 4, 5]);

  return (
    <div>
      <button onClick={() => set([1, 2, 3])}>Set to [1, 2, 3]</button>
      <button onClick={() => push(Math.floor(100 * Math.random()))}>
        Push
      </button>
      <button onClick={() => updateAt(1, Math.floor(100 * Math.random()))}>
        Update
      </button>
      <button onClick={() => removeAt(1)}>Remove index 1</button>
      <button onClick={() => filter(item => item % 2 === 0)}>
        Filter even values
      </button>
      <button onClick={() => sort((a, b) => a - b)}>Sort ascending</button>
      <button onClick={() => sort((a, b) => b - a)}>Sort descending</button>
      <button onClick={clear}>Clear</button>
      <button onClick={reset}>Reset</button>
      <pre>{JSON.stringify(list, null, 2)}</pre>
    </div>
  );
}

We call the useList hook with an initial array as the argument.

It returns an object with various properties and the array itself.

list has the value of the array.

set lets us set the array to a different array.

push lets us append an entry to the list array.

insertAt lets us insert an element to the list array.

update lets us update a list entry.

updateFirst updates the first entry of list.

upsert lets us insert or update an entry of list.

sort lets us sort our the list array.

filter filters the the list array.

removeAt removes a list entry with the given index.

clear empties the list array.

reset resets the list array to the initial value.

Conclusion

The react-use library lets us create a toggle, number, and list state we can manipulate easily.