2020-07-30 17:30:45 +00:00
|
|
|
import React, { useEffect, useRef, useState } from 'react';
|
2020-07-20 22:08:03 +00:00
|
|
|
|
|
|
|
export const noop = () => {};
|
|
|
|
|
|
|
|
export const useDidUpdate = (callback, deps) => {
|
|
|
|
const hasMount = useRef(false);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (hasMount.current) {
|
|
|
|
callback();
|
|
|
|
} else {
|
|
|
|
hasMount.current = true;
|
|
|
|
}
|
|
|
|
}, deps);
|
|
|
|
};
|
2020-07-29 18:15:55 +00:00
|
|
|
|
2020-07-29 19:01:40 +00:00
|
|
|
// Usage: const ref = useModalBehavior(() => setSomeState(false))
|
|
|
|
// place this ref on a component
|
|
|
|
export const useModalBehavior = (hideOverlay) => {
|
2020-07-29 18:15:55 +00:00
|
|
|
const ref = useRef({});
|
2020-07-29 19:01:40 +00:00
|
|
|
|
|
|
|
// Return values
|
2020-07-29 18:15:55 +00:00
|
|
|
const setRef = (r) => { ref.current = r; };
|
2020-08-03 17:48:10 +00:00
|
|
|
const [visible, setVisible] = useState(false);
|
2020-07-30 19:16:47 +00:00
|
|
|
const trigger = () => setVisible(!visible);
|
2020-07-29 19:01:40 +00:00
|
|
|
|
|
|
|
const hide = () => setVisible(false);
|
|
|
|
|
2020-07-29 18:15:55 +00:00
|
|
|
|
|
|
|
const handleClickOutside = ({ target }) => {
|
2020-08-11 16:00:36 +00:00
|
|
|
if (ref && ref.current && !(ref.current.contains && ref.current.contains(target))) {
|
2020-07-29 19:01:40 +00:00
|
|
|
hide();
|
2020-07-29 18:15:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
}, [ref]);
|
|
|
|
|
2020-07-29 19:01:40 +00:00
|
|
|
return [visible, trigger, setRef];
|
|
|
|
};
|
2020-08-13 20:02:39 +00:00
|
|
|
|
|
|
|
// Usage: useEffectWithComparison((props, prevProps) => { ... }, { prop1, prop2 })
|
|
|
|
// This hook basically applies useEffect but keeping track of the last value of relevant props
|
|
|
|
// So you can passa a 2-param function to capture new and old values and do whatever with them.
|
2020-08-13 20:22:03 +00:00
|
|
|
export const useEffectWithComparison = (fn, props) => {
|
2020-08-13 20:02:39 +00:00
|
|
|
const [prevProps, update] = useState({});
|
|
|
|
|
|
|
|
return useEffect(() => {
|
|
|
|
fn(props, prevProps);
|
|
|
|
update(props);
|
|
|
|
}, Object.values(props));
|
|
|
|
};
|
2020-08-13 20:27:38 +00:00
|
|
|
|
2020-08-13 21:57:42 +00:00
|
|
|
export const useEventListener = (event, callback, useCapture = false, list = []) => useEffect(() => {
|
2020-08-13 20:27:38 +00:00
|
|
|
document.addEventListener(event, callback, useCapture);
|
2020-08-13 21:34:35 +00:00
|
|
|
return () => document.removeEventListener(event, callback, useCapture);
|
2020-08-13 21:57:42 +00:00
|
|
|
}, list);
|