Update hook descriptions

This commit is contained in:
Isabelle Viktoria Maciohsek
2020-11-16 14:17:53 +02:00
parent 9e9e7443c2
commit eeccde742b
13 changed files with 121 additions and 96 deletions

View File

@ -3,27 +3,27 @@ title: useAsync
tags: hooks,state,reducer,advanced tags: hooks,state,reducer,advanced
--- ---
A hook that handles asynchronous calls. Handles asynchronous calls.
- Create a custom hook that takes a handler function, `fn`. - Create a custom hook that takes a handler function, `fn`.
- Define a reducer function and an initial state for the custom hook's state. - Define a reducer function and an initial state for the custom hook's state.
- Use the `React.useReducer()` hook to initialize the `state` variable and the `dispatch` function. - Use the `useReducer()` hook to initialize the `state` variable and the `dispatch` function.
- Define a `run` function that will run the provided callback, `fn`, while using `dispatch` to update `state` as necessary. - Define an asynchronous `run` function that will run the provided callback, `fn`, while using `dispatch` to update `state` as necessary.
- Return an object containting the the properties of `state` (`value`, `error` and `loading`) and the `run` function. - Return an object containting the properties of `state` (`value`, `error` and `loading`) and the `run` function.
```jsx ```jsx
const useAsync = (fn) => { const useAsync = fn => {
const initialState = { loading: false, error: null, value: null }; const initialState = { loading: false, error: null, value: null };
const stateReducer = (_, action) => { const stateReducer = (_, action) => {
switch (action.type) { switch (action.type) {
case 'start': case 'start':
return { loading: true, error: null, value: null}; return { loading: true, error: null, value: null };
case 'finish': case 'finish':
return { loading: false, error: null, value: action.value}; return { loading: false, error: null, value: action.value };
case 'error': case 'error':
return { loading: false, error: action.error, value: null}; return { loading: false, error: action.error, value: null };
}
} }
};
const [state, dispatch] = React.useReducer(stateReducer, initialState); const [state, dispatch] = React.useReducer(stateReducer, initialState);
@ -43,20 +43,29 @@ const useAsync = (fn) => {
```jsx ```jsx
const RandomImage = props => { const RandomImage = props => {
const imgFetch = useAsync(url => fetch(url).then(response => response.json())); const imgFetch = useAsync(url =>
fetch(url).then(response => response.json())
);
return ( return (
<div> <div>
<button <button
onClick={() => imgFetch.run('https://dog.ceo/api/breeds/image/random')} onClick={() => imgFetch.run('https://dog.ceo/api/breeds/image/random')}
disabled={ imgFetch.isLoading } disabled={imgFetch.isLoading}
> >
Load image Load image
</button> </button>
<br/> <br />
{ imgFetch.loading && <div>Loading...</div> } {imgFetch.loading && <div>Loading...</div>}
{ imgFetch.error && <div>Error { imgFetch.error }</div> } {imgFetch.error && <div>Error {imgFetch.error}</div>}
{ imgFetch.value && <img src={ imgFetch.value.message } alt="avatar" width={400} height="auto" />} {imgFetch.value && (
<img
src={imgFetch.value.message}
alt="avatar"
width={400}
height="auto"
/>
)}
</div> </div>
); );
}; };

View File

@ -3,11 +3,11 @@ title: useClickInside
tags: hooks,effect,event,intermediate tags: hooks,effect,event,intermediate
--- ---
A hook that handles the event of clicking inside the wrapped component. Handles the event of clicking inside the wrapped component.
- Create a custom hook that takes a `ref` and a `callback` to handle the `click` event. - Create a custom hook that takes a `ref` and a `callback` to handle the `'click'` event.
- Use the `React.useEffect()` hook to append and clean up the `click` event. - Use the `useEffect()` hook to append and clean up the `click` event.
- Use the `React.useRef()` hook to create a `ref` for your click component and pass it to the `useClickInside` hook. - Use the `useRef()` hook to create a `ref` for your click component and pass it to the `useClickInside` hook.
```jsx ```jsx
const useClickInside = (ref, callback) => { const useClickInside = (ref, callback) => {

View File

@ -3,11 +3,11 @@ title: useClickOutside
tags: hooks,effect,event,intermediate tags: hooks,effect,event,intermediate
--- ---
A hook that handles the event of clicking outside of the wrapped component. Handles the event of clicking outside of the wrapped component.
- Create a custom hook that takes a `ref` and a `callback` to handle the `click` event. - Create a custom hook that takes a `ref` and a `callback` to handle the `click` event.
- Use the `React.useEffect()` hook to append and clean up the `click` event. - Use the `useEffect()` hook to append and clean up the `click` event.
- Use the `React.useRef()` hook to create a `ref` for your click component and pass it to the `useClickOutside` hook. - Use the `useRef()` hook to create a `ref` for your click component and pass it to the `useClickOutside` hook.
```jsx ```jsx
const useClickOutside = (ref, callback) => { const useClickOutside = (ref, callback) => {

View File

@ -3,16 +3,17 @@ title: useComponentDidMount
tags: hooks,effect,beginner tags: hooks,effect,beginner
--- ---
A hook that executes a callback immediately after a component is mounted. Executes a callback immediately after a component is mounted.
- Use `React.useEffect()` with an empty array as the second argument to execute the provided callback only once when the component is mounted. - Use `useEffect()` with an empty array as the second argument to execute the provided callback only once when the component is mounted.
- Behaves like the `componentDidMount()` lifecycle method of class components.
```jsx ```jsx
const useComponentDidMount = onMountHandler => { const useComponentDidMount = onMountHandler => {
React.useEffect(() => { React.useEffect(() => {
onMountHandler() onMountHandler();
}, []); }, []);
} };
``` ```
```jsx ```jsx
@ -20,7 +21,7 @@ const Mounter = () => {
useComponentDidMount(() => console.log('Component did mount')); useComponentDidMount(() => console.log('Component did mount'));
return <div>Check the console!</div>; return <div>Check the console!</div>;
} };
ReactDOM.render(<Mounter />, document.getElementById('root')); ReactDOM.render(<Mounter />, document.getElementById('root'));
``` ```

View File

@ -3,16 +3,20 @@ title: useComponentWillUnmount
tags: hooks,effect,beginner tags: hooks,effect,beginner
--- ---
A hook that executes a callback immediately before a component is unmounted and destroyed. Executes a callback immediately before a component is unmounted and destroyed.
- Use `React.useEffect()` with an empty array as the second argument and return the provided callback to be executed only once before cleanup. - Use `useEffect()` with an empty array as the second argument and return the provided callback to be executed only once before cleanup.
- Behaves like the `componentWillUnmount()` lifecycle method of class components.
```jsx ```jsx
const useComponentWillUnmount = onUnmountHandler => { const useComponentWillUnmount = onUnmountHandler => {
React.useEffect(() => () => { React.useEffect(
onUnmountHandler() () => () => {
}, []); onUnmountHandler();
} },
[]
);
};
``` ```
```jsx ```jsx
@ -20,7 +24,7 @@ const Unmounter = () => {
useComponentWillUnmount(() => console.log('Component will unmount')); useComponentWillUnmount(() => console.log('Component will unmount'));
return <div>Check the console!</div>; return <div>Check the console!</div>;
} };
ReactDOM.render(<Unmounter />, document.getElementById('root')); ReactDOM.render(<Unmounter />, document.getElementById('root'));
``` ```

View File

@ -3,17 +3,17 @@ title: useCopyToClipboard
tags: hooks,effect,state,callback,advanced tags: hooks,effect,state,callback,advanced
--- ---
A hook that copies the given text to the clipboard. Copies the given text to the clipboard.
- Use the [copyToClipboard](/js/s/copy-to-clipboard/) snippet to copy the text to clipboard. - Use the [copyToClipboard](/js/s/copy-to-clipboard/) snippet to copy the text to clipboard.
- Use the `React.useState()` hook to initialize the `copied` variable. - Use the `useState()` hook to initialize the `copied` variable.
- Use the `React.useCallback()` hook to create a callback for the `copyToClipboard` method. - Use the `useCallback()` hook to create a callback for the `copyToClipboard` method.
- Use the `React.useEffect()` hook to reset the `copied` state variable if the `text` changes. - Use the `useEffect()` hook to reset the `copied` state variable if the `text` changes.
- Return the `copied` state variable and the `copy` callback. - Return the `copied` state variable and the `copy` callback.
```jsx ```jsx
const useCopyToClipboard = (text) => { const useCopyToClipboard = text => {
const copyToClipboard = (str) => { const copyToClipboard = str => {
const el = document.createElement('textarea'); const el = document.createElement('textarea');
el.value = str; el.value = str;
el.setAttribute('readonly', ''); el.setAttribute('readonly', '');
@ -46,7 +46,7 @@ const useCopyToClipboard = (text) => {
``` ```
```jsx ```jsx
const TextCopy = (props) => { const TextCopy = props => {
const [copied, copy] = useCopyToClipboard('Lorem ipsum'); const [copied, copy] = useCopyToClipboard('Lorem ipsum');
return ( return (
<div> <div>

View File

@ -3,11 +3,11 @@ title: useFetch
tags: hooks,effect,state,intermediate tags: hooks,effect,state,intermediate
--- ---
A hook that implements `fetch` in a declarative manner. Implements `fetch` in a declarative manner.
- Create a custom hook that takes a `url` and `options`. - Create a custom hook that takes a `url` and `options`.
- Use the `React.useState()` hook to initialize the `response` and `error` state variables. - Use the `useState()` hook to initialize the `response` and `error` state variables.
- Use the `React.useEffect()` hook to anychronously call `fetch()` and update the state varaibles accordingly. - Use the `useEffect()` hook to anychronously call `fetch()` and update the state variables accordingly.
- Return an object containting the `response` and `error` state variables. - Return an object containting the `response` and `error` state variables.
```jsx ```jsx

View File

@ -3,12 +3,12 @@ title: useInterval
tags: hooks,effect,intermediate tags: hooks,effect,intermediate
--- ---
A hook that implements `setInterval` in a declarative manner. Implements `setInterval` in a declarative manner.
- Create a custom hook that takes a `callback` and a `delay`. - Create a custom hook that takes a `callback` and a `delay`.
- Use the `React.useRef()` hook to create a `ref` for the callback function. - Use the `useRef()` hook to create a `ref` for the callback function.
- Use the `React.useEffect()` hook to remember the latest callback. - Use a `useEffect()` hook to remember the latest `callback` whenever it changes.
- Use the `React.useEffect()` hook to set up the interval and clean up. - Use a `useEffect()` hook dependent on `delay` to set up the interval and clean up.
```jsx ```jsx
const useInterval = (callback, delay) => { const useInterval = (callback, delay) => {

View File

@ -3,16 +3,17 @@ title: useMediaQuery
tags: hooks,state,effect,intermediate tags: hooks,state,effect,intermediate
--- ---
A hook that returns a value based on a media query. Checks if the current environment matches a given media query and returns the appropriate value.
- Check if `window` and `window.matchMedia` exist, return `whenFalse` if not. - Check if `window` and `window.matchMedia` exist, return `whenFalse` if not (e.g. SSR environment or unsupported browser).
- Use `window.matchMedia()` to match the given `query`, cast its `matches` property to a boolean and store in a state variable, `match`, using `React.useState()`. - Use `window.matchMedia()` to match the given `query`, cast its `matches` property to a boolean and store in a state variable, `match`, using the `useState()` hook.
- Use `React.useEffect()` to add a listener for changes and to clean up the listeners after the hook is destroyed. - Use the `useEffect()` hook to add a listener for changes and to clean up the listeners after the hook is destroyed.
- Return either `whenTrue` or `whenFalse` based on the value of `match`. - Return either `whenTrue` or `whenFalse` based on the value of `match`.
```jsx ```jsx
const useMediaQuery = (query, whenTrue, whenFalse) => { const useMediaQuery = (query, whenTrue, whenFalse) => {
if (typeof window === 'undefined' || typeof window.matchMedia === 'undefined') return whenFalse; if (typeof window === 'undefined' || typeof window.matchMedia === 'undefined')
return whenFalse;
const mediaQuery = window.matchMedia(query); const mediaQuery = window.matchMedia(query);
const [match, setMatch] = React.useState(!!mediaQuery.matches); const [match, setMatch] = React.useState(!!mediaQuery.matches);
@ -30,11 +31,13 @@ const useMediaQuery = (query, whenTrue, whenFalse) => {
```jsx ```jsx
const ResponsiveText = () => { const ResponsiveText = () => {
const text = useMediaQuery( const text = useMediaQuery(
'(max-width: 400px)', 'Less than 400px wide', 'More than 400px wide' '(max-width: 400px)',
'Less than 400px wide',
'More than 400px wide'
); );
return <span>{text}</span>; return <span>{text}</span>;
} };
ReactDOM.render(<ResponsiveText />, document.getElementById('root')); ReactDOM.render(<ResponsiveText />, document.getElementById('root'));
``` ```

View File

@ -3,16 +3,16 @@ title: useNavigatorOnLine
tags: hooks,state,effect,intermediate tags: hooks,state,effect,intermediate
--- ---
A hook that returns if the client is online or offline. Checks if the client is online or offline.
- Create a function, `getOnLineStatus`, that uses the `NavigatorOnLine` web API to get the online status of the client. - Create a function, `getOnLineStatus`, that uses the `NavigatorOnLine` web API to get the online status of the client.
- Use the `React.useState()` hook to create an appropriate state variable, `status`, and setter. - Use the `useState()` hook to create an appropriate state variable, `status`, and setter.
- Use the `React.useEffect()` hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting. - Use the `useEffect()` hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting.
- Finally return the `status` state variable. - Finally return the `status` state variable.
```jsx ```jsx
const getOnLineStatus = () => const getOnLineStatus = () =>
typeof navigator !== "undefined" && typeof navigator.onLine === "boolean" typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean'
? navigator.onLine ? navigator.onLine
: true; : true;
@ -23,12 +23,12 @@ const useNavigatorOnLine = () => {
const setOffline = () => setStatus(false); const setOffline = () => setStatus(false);
React.useEffect(() => { React.useEffect(() => {
window.addEventListener("online", setOnline); window.addEventListener('online', setOnline);
window.addEventListener("offline", setOffline); window.addEventListener('offline', setOffline);
return () => { return () => {
window.removeEventListener("online", setOnline); window.removeEventListener('online', setOnline);
window.removeEventListener("offline", setOffline); window.removeEventListener('offline', setOffline);
}; };
}, []); }, []);
@ -40,8 +40,8 @@ const useNavigatorOnLine = () => {
const StatusIndicator = () => { const StatusIndicator = () => {
const isOnline = useNavigatorOnLine(); const isOnline = useNavigatorOnLine();
return <span>You are {isOnline ? "online" : "offline"}.</span>; return <span>You are {isOnline ? 'online' : 'offline'}.</span>;
}; };
ReactDOM.render(<StatusIndicator />, document.getElementById("root")); ReactDOM.render(<StatusIndicator />, document.getElementById('root'));
``` ```

View File

@ -1,13 +1,13 @@
--- ---
title: usePrevious title: usePrevious
tags: hooks,state,effect,intermediate tags: hooks,state,effect,beginner
--- ---
A hook that stores the previous state or props. Stores the previous state or props.
- Create a custom hook that takes a `value`. - Create a custom hook that takes a `value`.
- Use the `React.useRef()` hook to create a `ref` for the `value`. - Use the `useRef()` hook to create a `ref` for the `value`.
- Use the `React.useEffect()` hook to remember the latest `value`. - Use the `useEffect()` hook to remember the latest `value`.
```jsx ```jsx
const usePrevious = value => { const usePrevious = value => {
@ -16,7 +16,7 @@ const usePrevious = value => {
ref.current = value; ref.current = value;
}); });
return ref.current; return ref.current;
} };
``` ```
```jsx ```jsx
@ -26,7 +26,9 @@ const Counter = () => {
return ( return (
<div> <div>
<p>Current: {value} - Previous: {lastValue}</p> <p>
Current: {value} - Previous: {lastValue}
</p>
<button onClick={() => setValue(value + 1)}>Increment</button> <button onClick={() => setValue(value + 1)}>Increment</button>
</div> </div>
); );

View File

@ -3,13 +3,13 @@ title: useSSR
tags: hooks,effect,state,memo,intermediate tags: hooks,effect,state,memo,intermediate
--- ---
A hook that checks if the code is running on the browser or the server. Checks if the code is running on the browser or the server.
- Create a custom hook that returns an appropriate object. - Create a custom hook that returns an appropriate object.
- Use `typeof window`, `window.document` and `window.document.createElement` to check if the code is running on the browser. - Use `typeof window`, `window.document` and `Document.createElement()` to check if the code is running on the browser.
- Use the `React.useState()` hook to define the `inBrowser` state variable. - Use the `useState()` hook to define the `inBrowser` state variable.
- Use the `React.useEffect()` hook to update the `inBrowser` state variable and clean up at the end. - Use the `useEffect()` hook to update the `inBrowser` state variable and clean up at the end.
- Use the `React.useMemo()` to memoize the return values of the custom hook. - Use the `useMemo()` hook to memoize the return values of the custom hook.
```jsx ```jsx
const isDOMavailable = !!( const isDOMavailable = !!(
@ -25,18 +25,24 @@ const useSSR = (callback, delay) => {
setInBrowser(isDOMavailable); setInBrowser(isDOMavailable);
return () => { return () => {
setInBrowser(false); setInBrowser(false);
} };
}, []); }, []);
const useSSRObject = React.useMemo(() => ({ const useSSRObject = React.useMemo(
() => ({
isBrowser: inBrowser, isBrowser: inBrowser,
isServer: !inBrowser, isServer: !inBrowser,
canUseWorkers: typeof Worker !== 'undefined', canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners: inBrowser && !!window.addEventListener, canUseEventListeners: inBrowser && !!window.addEventListener,
canUseViewport: inBrowser && !!window.screen canUseViewport: inBrowser && !!window.screen
}), [inBrowser]); }),
[inBrowser]
);
return React.useMemo(() => Object.assign(Object.values(useSSRObject), useSSRObject), [inBrowser]); return React.useMemo(
() => Object.assign(Object.values(useSSRObject), useSSRObject),
[inBrowser]
);
}; };
``` ```
@ -44,7 +50,7 @@ const useSSR = (callback, delay) => {
const SSRChecker = props => { const SSRChecker = props => {
let { isBrowser, isServer } = useSSR(); let { isBrowser, isServer } = useSSR();
return <p>{ isBrowser ? 'Running on browser' : 'Running on server' }</p>; return <p>{isBrowser ? 'Running on browser' : 'Running on server'}</p>;
}; };
ReactDOM.render(<SSRChecker />, document.getElementById('root')); ReactDOM.render(<SSRChecker />, document.getElementById('root'));

View File

@ -3,12 +3,12 @@ title: useTimeout
tags: hooks,effect,intermediate tags: hooks,effect,intermediate
--- ---
A hook that implements `setTimeout` in a declarative manner. Implements `setTimeout` in a declarative manner.
- Create a custom hook that takes a `callback` and a `delay`. - Create a custom hook that takes a `callback` and a `delay`.
- Use the `React.useRef()` hook to create a `ref` for the callback function. - Use the `useRef()` hook to create a `ref` for the callback function.
- Use the `React.useEffect()` hook to remember the latest callback. - Use the `useEffect()` hook to remember the latest callback.
- Use the `React.useEffect()` hook to set up the timeout and clean up. - Use the `useEffect()` hook to set up the timeout and clean up.
```jsx ```jsx
const useTimeout = (callback, delay) => { const useTimeout = (callback, delay) => {