React JS Hooks - spinningideas/resources GitHub Wiki

Rules For Hooks

  • Can only used in functional components

  • Must be declared very top of component (on first lines)

  • Cannot return from component before any hook definition (eg cannot return render function before hooks)

  • Name of hook must start with "use"

  • Cannot have "if" statements in or around hook execution (must always execute or use hook and not do so conditionally)

Types of Hooks

Component State Hooks

Used for managing component state or data and two way binding of data to component markup

useState (Local component state)

Declare state

const [name, setValue] = useState ('defaultvalue')

Read Only State

At times you may need to use a dynamic state bag that is set upon component render but NOT updated after.

Example:

const [value, setValue] = useState (
// Evaluated only at first rendering due to return of empty array
() => computeValue ()
,[])

Update state

If your new state relies on the value of the old state, you should always use a function as the argument. If you are setting a value that does not rely on the value of the old state, then you can use a value as the argument.

NOTE: Do not use setValue ('newvalue') as state updates are batched and multiple updates to the enabled/disabled state are made together, each update will rely on the correct previous state so that you always end up with the result you expect.

Example:

DO THIS:
setValue ((value) => 'newvalue')

NOT THIS:
setValue ('newvalue')

Component Lifecycle Hooks

Used for initializing state based on whether component has loaded or triggering side effects within component if state changes

useEffect

Execute only once (due to empty dependency array)

useEffect (() => {
  makeHttpRequest()
}, [])

Execute once initially then again only if value of "foo" changes (due to "foo" being in the dependency array)

useEffect (() => {
  makeHttpRequest(foo)
}, [foo])

Cleanup after execution (due to use of return of "clearTimeout" which will handle removing the timeout and thus clean it up)

useEffect (() => {
  let timeout = setTimeout (makeHttpRequest, 5000 )
  return () => clearTimeout (timeout)
}, [])

Async Update state - call async based methods from useEffect

useEffect (() => {
  const issueSearchOnLoad = async () => {
    let searchResults = await performSearch();
    setState(searchResults);
  }
  issueSearchOnLoad();
}, [])

Context Hooks - Application State

Used to manage state shared between components or across the application (for example the application theme)

Define the Context

Declare instance

export const ThemeContext = createContext();

Define Provider with any state

import ThemeContext from 'contexts/ThemeContext';

export const ThemeProvider = ({ children, initialTheme = 'light' }) => {
const [theme, setTheme] = useState (initialTheme)
return (
  <ThemeContext.Provider value ={[theme, setTheme]}>
    {children}
  </ThemeContext.Provider>
)
}

Reference the Provider in application

import ThemeProvider from 'contexts/ThemeProvider';

<ThemeProvider initialTheme="light">
  <app></app>
</ThemeProvider>

Reference Provider in Components (to perhaps modify state or change the value of theme)

import ThemeContext from 'contexts/ThemeContext';

const themeContext= useContext(ThemeContext);

const updateTheme =(theme)=>{
  themeContext.setTheme(theme);
}

Reference Hooks

Used to store mutable reference to something in a given component that will persist for the full lifetime of the component. Useful for storing references to dom elements that need to be referred to and modified (eg get the width or height of div or focus a text input)

Example


const domElementRef = useRef();

const getDivHeight =()=> {
  let height = domElementRef.current.clientHeight;
}

<div ref={domElementRef } />
<button onClick={getDivHeight ()} />

Custom Hooks - Create your own

You can pull in hooks from various sources or create your own as needed - below is an example of hook that provides the end users geo location data in the form of lat/lng and a boolean indicating whether their location could be determined via the built in browser capability

Hook Definition

const useGeolocation = () => {
  const [locationAvailable, setLocationAvailable] = useState (false)
  const [latitude, setLatitude] = useState (undefined)
  const [longitude, setLongitude] = useState (undefined)

  useEffect (() => {
    navigator.geolocation. getCurrentPosition (
      (res) => {
        locationAvailable(true)
        setLatitude (res.coords.latitude)
        setLongitude (res.coords.longitude)
    },
    (err) => {
      locationAvailable(false)
    })
  }, [])

  return { locationAvailable, latitude, longitude }
}

Hook Example Usage

const { locationAvailable, latitude, longitude } = useGeolocation()
⚠️ **GitHub.com Fallback** ⚠️