Skip to content

Instantly share code, notes, and snippets.

@spion
Last active April 13, 2022 18:29
Show Gist options
  • Save spion/09af04ea2ae8b6858e8edce11002b063 to your computer and use it in GitHub Desktop.
Save spion/09af04ea2ae8b6858e8edce11002b063 to your computer and use it in GitHub Desktop.
/**
* Creates a manually triggered effect which runs after all the state updates have completed.
*
* You can use it to trigger the same effect from several different places (such as a button click,
* dropdown change etc) after also performing state updates from the same event.
*
* When to use instead of `useEffect`? When dependencies should not automatically trigger it
* When to use instead of a plain function? When you want to update some state before running the effect
*
* @example
*
* ```
* const [selectedOption, setSelectedOption] = useState(...)
* const [text, setText] = useState(...)
*
* const performSearch = useManualEffect(() => {
* axios.get('/api/search', {params: {selectedOption, text}});
* })
*
* return <>
* <Dropdown
* options={options}
* selectedOption={selectedOption}
* onChange={val => { setSelectedOption(val); performSearch(); }}
* />
* <input type={text} onChange={e => setText(e.target.value)} />
* <button onClick={performSearch}>Search</Button>
* </>
* ```
*/
function useManualEffect(fn: EffectCallback): () => void {
const [event, setEvent] = useState<null | {}>(null);
useEffect(() => {
if (event !== null) return fn()
}, [event]);
return () => setEvent({})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment