lifecycle HOCs with Recompose
timeouts
by jonahe
HTML
<script src="https://unpkg.com/[email protected]/dist/react-with-addons.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>
<script src="https://unpkg.com/[email protected]/build/Recompose.js"></script>
<div id="root"></div>
Babel + JSX
const { compose, withStateHandlers, branch, lifecycle } = Recompose;
const withNamedToggler = (propertyNameBase, initialValue) => withStateHandlers(
{ [`${propertyNameBase}IsToggled`] : initialValue },
{
[`${propertyNameBase}Toggler`] : props => (e) => {
return { [`${propertyNameBase}IsToggled`]: !props[`${propertyNameBase}IsToggled`] };
}
}
);
/*
EXECUTES A FUNCTION AFTER A DELAY. Handles clearing timeout on unmount (needs testing)
propsToFunctionToRun : a function like props => props.theFunctionToRun
delayInMs : delay in milliseconds
name: name to be used for generating keys/names for values and functions
For a name like "testTimeout", Will produce
testTimeout : A number referencing the timeout
testTimeoutClearer: A function to clear the timeout
testTimoutHasCleared: a bool indicating whether the timeout has been cleared
*/
const withTimeout = (propsToFunctionToRun, delayInMs, name = `timeout_${(Math.random() * 1000).toFixed(0)}`, autoStart = true) => {
const timeoutKey = `${name}`;
// const timeoutHasStartedKey = `${name}HasStarted`;
const timeoutStarterKey = `${timeoutKey}Starter`;
const timeoutClearerKey = `${name}Clearer`;
const timeoutIsClearedKey = `${name}IsCleared`;
const timeoutHasExecutedKey = `${name}HasExecuted`;
return compose(
// handle
lifecycle({
state: { [timeoutKey]: null, [timeoutHasExecutedKey] : false },
executeFunction() {
const functionToRun = propsToFunctionToRun(this.props);
functionToRun();
this.setState({ [timeoutHasExecutedKey] : true });
},
componentDidMount() {
if(!autoStart) return;
const timeoutRef = setTimeout(this.executeFunction.bind(this), delayInMs);
this.setState({[timeoutKey] : timeoutRef});
},
componentWillUnmount() {
console.log('unmount. clearing ref', this.state[timeoutKey])
const { [timeoutHasExecutedKey] : hasExecuted } = this.state;
...