Skip to content

Instantly share code, notes, and snippets.

@chaance
Last active May 29, 2019 23:39
Show Gist options
  • Save chaance/1f4b4533db9092db6f7ce8bfef77ba56 to your computer and use it in GitHub Desktop.
Save chaance/1f4b4533db9092db6f7ce8bfef77ba56 to your computer and use it in GitHub Desktop.
Some handy hooks for React
import React from 'react';
import flattenInput from './utils/flattenInput';
/**
* Store a component's previous value in a ref for use after the value changes.
*
* const prevProps = usePrevious(props);
* const { children: prevChildren } = usePrevious(props) || {};
* const prevState = usePrevious(state);
*/
export function usePrevious(value) {
const ref = React.useRef();
React.useEffect(
() => {
ref.current = value;
}
);
return ref.current;
}
/**
* Get data and loading state from any function that returns a promise.
* returns { isLoading, data, error }
*/
export function usePromise(fn) {
const inputs = Array.from(arguments);
const [state, setState] = React.useState({ isLoading: false });
React.useEffect(() => {
if (!fn) {
return;
}
setState({ data: state.data, isLoading: true });
fn
.apply(null, inputs)
.then(data => {
setState({
data,
isLoading: false,
});
})
.catch(error => {
setState({
error,
isLoading: false,
});
});
}, flattenInput(inputs));
return state;
}
export function flattenInput() {
let res = [];
const args = Array.from(arguments);
args.forEach(input => {
if (input instanceof Array) {
input.forEach(item => {
res = res.concat(flattenInput(item));
});
} else if (input instanceof URL) {
res = res.concat(input.toJSON());
} else if (input instanceof Object) {
const keys = Object.keys(input);
keys.forEach(key => {
res = res.concat([key]).concat(flattenInput(input[key]));
});
} else {
res = res.concat(input);
}
});
return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment