James Sherry
Web Development Tutor and Co-Founder of { The Jump } Digital School
(although they're now available with other frameworks)
First read the Rules of Hooks
OK, now let's go...
const something[s]ToHelpYouUseIt? = hookFunction(arguments);When you call the hookFunction you pass it [generally 'starting] arguments'/defaults it needs to setup
You get them all from the react package:
import React, { useState, useEffect, etc } from 'react';Replaces state we get from classes
const [count, setCount] = useState(0);You use it like so:
So, from our Anatomy of hooks...
const something[s]ToHelpYouUseIt? = hookFunction(arguments);Replaces componentDidMount & componentDidUpdate [& componentWillUnmount]
useEffect(/* Callback */, [/* dependancies */]You use it like so:
So practically
useEffect(
  // Callback
  () => {
    // Do something on mounting/updating
    const handler = setTimeout(() => {
    // just using a timeont as an example because it needs cleanup
    }, delay);
    // [optionally] Clean up when done (componentWillUnmount)
    return () => {
      clearTimeout(handler);
    };
  },
  // Dependancies:
  [value, delay] // Only re-run effect if these values change
);
There is a rule in the eslint package that will help you (react-hooks/exhaustive-deps)
A nicer way of using the context API
const initialState = {count: 0};
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);const memoizedValue = useMemo(
  () => computeExpensiveValue(a, b), 
  [a, b]
);function TextInputWithFocusButton() {
  const inputEl = useRef();
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}import { useRef, useImperativeHandle, forwardRef}
function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
export default FancyInput  // useEffect(() => {
  useLayoutEffect(() => {
    listRef.current.scrollTop = listRef.current.scrollHeight;
  });function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);
  // ...
  // Show a label in DevTools next to this Hook
  // e.g. "FriendStatus: Online"
  useDebugValue(isOnline ? 'Online' : 'Offline');
  return isOnline;
}function NameFields() {
  const id = useId();
  return (
    <div>
      <label htmlFor={id + '-firstName'}>First Name</label>
      <div>
        <input id={id + '-firstName'} type="text" />
      </div>
      <label htmlFor={id + '-lastName'}>Last Name</label>
      <div>
        <input id={id + '-lastName'} type="text" />
      </div>
    </div>
  );
}function Typeahead() {
  const query = useSearchQuery('');
  const deferredQuery = useDeferredValue(query);
  // Memoizing tells React to only re-render when deferredQuery changes,
  // not when query changes.
  const suggestions = useMemo(() =>
    <SearchSuggestions query={deferredQuery} />,
    [deferredQuery]
  );
  return (
    <>
      <SearchInput query={query} />
      <Suspense fallback="Loading results...">
        {suggestions}
      </Suspense>
    </>
  );
}  const [searchTerm, setSearchTerm] = useState("");
  const [data, setData] = useState(USERS);
  const [isPending, startTransition] = useTransition();
  function handleChange(value) {
    setSearchTerm(value); // more important
    startTransition(() => { // less important
      setData(filterUsers(value));
    });
  }
return (
  <>
    <input value={searchTerm} onChange={handleChange} />
    {isPending ? <p>Updating list</p> : null}
    <PeopleList people={data} />
  </>
)
By James Sherry
A short guide to using hooks in react