React JS Hooks - spinningideas/resources GitHub Wiki
-
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)
Used for managing component state or data and two way binding of data to component markup
const [name, setValue] = useState ('defaultvalue')
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 ()
,[])
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')
Used for initializing state based on whether component has loaded or triggering side effects within component if state changes
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)
}, [])
useEffect (() => {
const issueSearchOnLoad = async () => {
let searchResults = await performSearch();
setState(searchResults);
}
issueSearchOnLoad();
}, [])
Used to manage state shared between components or across the application (for example the application theme)
export const ThemeContext = createContext();
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>
)
}
import ThemeProvider from 'contexts/ThemeProvider';
<ThemeProvider initialTheme="light">
<app></app>
</ThemeProvider>
import ThemeContext from 'contexts/ThemeContext';
const themeContext= useContext(ThemeContext);
const updateTheme =(theme)=>{
themeContext.setTheme(theme);
}
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)
const domElementRef = useRef();
const getDivHeight =()=> {
let height = domElementRef.current.clientHeight;
}
<div ref={domElementRef } />
<button onClick={getDivHeight ()} />
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
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 }
}
const { locationAvailable, latitude, longitude } = useGeolocation()