diff --git a/snippets/useAsync.md b/snippets/useAsync.md index 9881094f3..a4449b3f6 100644 --- a/snippets/useAsync.md +++ b/snippets/useAsync.md @@ -3,27 +3,27 @@ title: useAsync tags: hooks,state,reducer,advanced --- -A hook that handles asynchronous calls. +Handles asynchronous calls. - Create a custom hook that takes a handler function, `fn`. - 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. -- Define a `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. +- Use the `useReducer()` hook to initialize the `state` variable and the `dispatch` function. +- 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 properties of `state` (`value`, `error` and `loading`) and the `run` function. ```jsx -const useAsync = (fn) => { +const useAsync = fn => { const initialState = { loading: false, error: null, value: null }; const stateReducer = (_, action) => { switch (action.type) { case 'start': - return { loading: true, error: null, value: null}; + return { loading: true, error: null, value: null }; case 'finish': - return { loading: false, error: null, value: action.value}; + return { loading: false, error: null, value: action.value }; 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); @@ -36,27 +36,36 @@ const useAsync = (fn) => { dispatch({ type: 'error', error }); } }; - + return { ...state, run }; }; ``` ```jsx const RandomImage = props => { - const imgFetch = useAsync(url => fetch(url).then(response => response.json())); - + const imgFetch = useAsync(url => + fetch(url).then(response => response.json()) + ); + return (
-
- { imgFetch.loading &&
Loading...
} - { imgFetch.error &&
Error { imgFetch.error }
} - { imgFetch.value && avatar} +
+ {imgFetch.loading &&
Loading...
} + {imgFetch.error &&
Error {imgFetch.error}
} + {imgFetch.value && ( + avatar + )}
); }; diff --git a/snippets/useClickInside.md b/snippets/useClickInside.md index 1d95bc7f5..c88bfd9e1 100644 --- a/snippets/useClickInside.md +++ b/snippets/useClickInside.md @@ -3,11 +3,11 @@ title: useClickInside 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. -- Use the `React.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. +- Create a custom hook that takes a `ref` and a `callback` to handle the `'click'` event. +- Use the `useEffect()` hook to append and clean up the `click` event. +- Use the `useRef()` hook to create a `ref` for your click component and pass it to the `useClickInside` hook. ```jsx const useClickInside = (ref, callback) => { diff --git a/snippets/useClickOutside.md b/snippets/useClickOutside.md index 8d56fffbc..9346acff7 100644 --- a/snippets/useClickOutside.md +++ b/snippets/useClickOutside.md @@ -3,11 +3,11 @@ title: useClickOutside 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. -- Use the `React.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 `useEffect()` hook to append and clean up the `click` event. +- Use the `useRef()` hook to create a `ref` for your click component and pass it to the `useClickOutside` hook. ```jsx const useClickOutside = (ref, callback) => { diff --git a/snippets/useComponentDidMount.md b/snippets/useComponentDidMount.md index 75d9996d4..faf178061 100644 --- a/snippets/useComponentDidMount.md +++ b/snippets/useComponentDidMount.md @@ -3,16 +3,17 @@ title: useComponentDidMount 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 const useComponentDidMount = onMountHandler => { React.useEffect(() => { - onMountHandler() + onMountHandler(); }, []); -} +}; ``` ```jsx @@ -20,7 +21,7 @@ const Mounter = () => { useComponentDidMount(() => console.log('Component did mount')); return
Check the console!
; -} +}; ReactDOM.render(, document.getElementById('root')); ``` diff --git a/snippets/useComponentWillUnmount.md b/snippets/useComponentWillUnmount.md index 737872e67..b793c3cc8 100644 --- a/snippets/useComponentWillUnmount.md +++ b/snippets/useComponentWillUnmount.md @@ -3,16 +3,20 @@ title: useComponentWillUnmount 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 const useComponentWillUnmount = onUnmountHandler => { - React.useEffect(() => () => { - onUnmountHandler() - }, []); -} + React.useEffect( + () => () => { + onUnmountHandler(); + }, + [] + ); +}; ``` ```jsx @@ -20,7 +24,7 @@ const Unmounter = () => { useComponentWillUnmount(() => console.log('Component will unmount')); return
Check the console!
; -} +}; ReactDOM.render(, document.getElementById('root')); ``` diff --git a/snippets/useCopyToClipboard.md b/snippets/useCopyToClipboard.md index b7b6e7db4..1bc01cb23 100644 --- a/snippets/useCopyToClipboard.md +++ b/snippets/useCopyToClipboard.md @@ -3,17 +3,17 @@ title: useCopyToClipboard 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 `React.useState()` hook to initialize the `copied` variable. -- Use the `React.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 `useState()` hook to initialize the `copied` variable. +- Use the `useCallback()` hook to create a callback for the `copyToClipboard` method. +- Use the `useEffect()` hook to reset the `copied` state variable if the `text` changes. - Return the `copied` state variable and the `copy` callback. ```jsx -const useCopyToClipboard = (text) => { - const copyToClipboard = (str) => { +const useCopyToClipboard = text => { + const copyToClipboard = str => { const el = document.createElement('textarea'); el.value = str; el.setAttribute('readonly', ''); @@ -46,7 +46,7 @@ const useCopyToClipboard = (text) => { ``` ```jsx -const TextCopy = (props) => { +const TextCopy = props => { const [copied, copy] = useCopyToClipboard('Lorem ipsum'); return (
diff --git a/snippets/useFetch.md b/snippets/useFetch.md index 8c229ce11..a5424a723 100644 --- a/snippets/useFetch.md +++ b/snippets/useFetch.md @@ -3,11 +3,11 @@ title: useFetch 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`. -- Use the `React.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 `useState()` hook to initialize the `response` and `error` state variables. +- Use the `useEffect()` hook to anychronously call `fetch()` and update the state variables accordingly. - Return an object containting the `response` and `error` state variables. ```jsx diff --git a/snippets/useInterval.md b/snippets/useInterval.md index 814dbd5ce..bf0de4559 100644 --- a/snippets/useInterval.md +++ b/snippets/useInterval.md @@ -3,12 +3,12 @@ title: useInterval 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`. -- Use the `React.useRef()` hook to create a `ref` for the callback function. -- Use the `React.useEffect()` hook to remember the latest callback. -- Use the `React.useEffect()` hook to set up the interval and clean up. +- Use the `useRef()` hook to create a `ref` for the callback function. +- Use a `useEffect()` hook to remember the latest `callback` whenever it changes. +- Use a `useEffect()` hook dependent on `delay` to set up the interval and clean up. ```jsx const useInterval = (callback, delay) => { diff --git a/snippets/useMediaQuery.md b/snippets/useMediaQuery.md index 5314eb1e3..7f50a02c9 100644 --- a/snippets/useMediaQuery.md +++ b/snippets/useMediaQuery.md @@ -3,21 +3,22 @@ title: useMediaQuery 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. -- 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 `React.useEffect()` to add a listener for changes and to clean up the listeners after the hook is destroyed. +- 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 the `useState()` hook. +- 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`. ```jsx 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 [match, setMatch] = React.useState(!!mediaQuery.matches); - React.useEffect(() => { + React.useEffect(() => { const handler = () => setMatch(!!mediaQuery.matches); mediaQuery.addListener(handler); return () => mediaQuery.removeListener(handler); @@ -30,11 +31,13 @@ const useMediaQuery = (query, whenTrue, whenFalse) => { ```jsx const ResponsiveText = () => { 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 {text}; -} +}; ReactDOM.render(, document.getElementById('root')); ``` diff --git a/snippets/useNavigatorOnLine.md b/snippets/useNavigatorOnLine.md index 52fabdaf1..fccf9401c 100644 --- a/snippets/useNavigatorOnLine.md +++ b/snippets/useNavigatorOnLine.md @@ -3,16 +3,16 @@ title: useNavigatorOnLine 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. -- Use the `React.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 `useState()` hook to create an appropriate state variable, `status`, and setter. +- Use the `useEffect()` hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting. - Finally return the `status` state variable. ```jsx const getOnLineStatus = () => - typeof navigator !== "undefined" && typeof navigator.onLine === "boolean" + typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean' ? navigator.onLine : true; @@ -23,12 +23,12 @@ const useNavigatorOnLine = () => { const setOffline = () => setStatus(false); React.useEffect(() => { - window.addEventListener("online", setOnline); - window.addEventListener("offline", setOffline); + window.addEventListener('online', setOnline); + window.addEventListener('offline', setOffline); return () => { - window.removeEventListener("online", setOnline); - window.removeEventListener("offline", setOffline); + window.removeEventListener('online', setOnline); + window.removeEventListener('offline', setOffline); }; }, []); @@ -40,8 +40,8 @@ const useNavigatorOnLine = () => { const StatusIndicator = () => { const isOnline = useNavigatorOnLine(); - return You are {isOnline ? "online" : "offline"}.; + return You are {isOnline ? 'online' : 'offline'}.; }; -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render(, document.getElementById('root')); ``` diff --git a/snippets/usePrevious.md b/snippets/usePrevious.md index c4323a131..53d25ad1c 100644 --- a/snippets/usePrevious.md +++ b/snippets/usePrevious.md @@ -1,13 +1,13 @@ --- 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`. -- Use the `React.useRef()` hook to create a `ref` for the `value`. -- Use the `React.useEffect()` hook to remember the latest `value`. +- Use the `useRef()` hook to create a `ref` for the `value`. +- Use the `useEffect()` hook to remember the latest `value`. ```jsx const usePrevious = value => { @@ -16,17 +16,19 @@ const usePrevious = value => { ref.current = value; }); return ref.current; -} +}; ``` ```jsx const Counter = () => { const [value, setValue] = React.useState(0); const lastValue = usePrevious(value); - + return (
-

Current: {value} - Previous: {lastValue}

+

+ Current: {value} - Previous: {lastValue} +

); diff --git a/snippets/useSSR.md b/snippets/useSSR.md index 355f63b81..7d85aac92 100644 --- a/snippets/useSSR.md +++ b/snippets/useSSR.md @@ -3,13 +3,13 @@ title: useSSR 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. -- Use `typeof window`, `window.document` and `window.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 `React.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 `typeof window`, `window.document` and `Document.createElement()` to check if the code is running on the browser. +- Use the `useState()` hook to define the `inBrowser` state variable. +- Use the `useEffect()` hook to update the `inBrowser` state variable and clean up at the end. +- Use the `useMemo()` hook to memoize the return values of the custom hook. ```jsx const isDOMavailable = !!( @@ -25,18 +25,24 @@ const useSSR = (callback, delay) => { setInBrowser(isDOMavailable); return () => { setInBrowser(false); - } + }; }, []); - const useSSRObject = React.useMemo(() => ({ - isBrowser: inBrowser, - isServer: !inBrowser, - canUseWorkers: typeof Worker !== 'undefined', - canUseEventListeners: inBrowser && !!window.addEventListener, - canUseViewport: inBrowser && !!window.screen - }), [inBrowser]); + const useSSRObject = React.useMemo( + () => ({ + isBrowser: inBrowser, + isServer: !inBrowser, + canUseWorkers: typeof Worker !== 'undefined', + canUseEventListeners: inBrowser && !!window.addEventListener, + canUseViewport: inBrowser && !!window.screen + }), + [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 => { let { isBrowser, isServer } = useSSR(); - return

{ isBrowser ? 'Running on browser' : 'Running on server' }

; + return

{isBrowser ? 'Running on browser' : 'Running on server'}

; }; ReactDOM.render(, document.getElementById('root')); diff --git a/snippets/useTimeout.md b/snippets/useTimeout.md index 444d57c73..01ac0773b 100644 --- a/snippets/useTimeout.md +++ b/snippets/useTimeout.md @@ -3,12 +3,12 @@ title: useTimeout 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`. -- Use the `React.useRef()` hook to create a `ref` for the callback function. -- Use the `React.useEffect()` hook to remember the latest callback. -- Use the `React.useEffect()` hook to set up the timeout and clean up. +- Use the `useRef()` hook to create a `ref` for the callback function. +- Use the `useEffect()` hook to remember the latest callback. +- Use the `useEffect()` hook to set up the timeout and clean up. ```jsx const useTimeout = (callback, delay) => {