@keislamoglu/react-conditional
Version:
Reduce the complexity of conditional rendering.
107 lines (96 loc) • 3.02 kB
JavaScript
import { useState, useCallback, useEffect, useRef } from 'react';
const useConditional = conditions => {
const [actions, _setActions] = useState(new Set());
const verifyAndPerformConditions = useCallback(() => {
const _actions = Array.from(actions);
conditions.forEach(condition => {
condition.verifyAndPerform(_actions);
});
}, [actions, conditions]);
const doAction = useCallback(action => {
_setActions(actions => {
if (actions.has(action)) {
return actions;
}
actions.add(action);
return new Set(actions);
});
}, []);
const undoAction = useCallback(action => {
_setActions(actions => {
if (!actions.has(action)) {
return actions;
}
actions.delete(action);
return new Set(actions);
});
}, []);
const clearActions = useCallback(() => {
_setActions(actions => {
if (actions.size === 0) {
return actions;
}
actions.clear();
return new Set(actions);
});
}, []);
const setActions = useCallback(_actions => {
_setActions(actions => {
if (_actions.length === actions.size && _actions.every(action => actions.has(action))) {
return actions;
}
actions.clear();
_actions.forEach(action => actions.add(action));
return new Set(actions);
});
}, []);
const verifyCondition = useCallback(when => {
return when == null || [!when.done || when.done.every(actionShouldDone => actions.has(actionShouldDone)), !when.undone || !when.undone.some(actionShouldUndone => actions.has(actionShouldUndone))].every(Boolean);
}, [actions]);
useEffect(() => {
verifyAndPerformConditions();
}, [verifyAndPerformConditions]);
return {
doAction,
undoAction,
clearActions,
setActions,
verifyCondition
};
};
const useCondition = (when, handler) => {
const performed = useRef(false);
const teardownFn = useRef();
const handlerRef = useRef(handler);
const verify = useCallback(actions => {
return when == null || [!when.done || when.done.every(actionShouldDone => actions.includes(actionShouldDone)), !when.undone || !when.undone.some(actionShouldUndone => actions.includes(actionShouldUndone))].every(Boolean);
}, [when]);
const perform = useCallback(() => {
if (performed.current) return;
performed.current = true;
return teardownFn.current = handler();
}, [handler]);
const revoke = useCallback(() => {
if (!performed.current) return;
performed.current = false;
teardownFn.current && teardownFn.current();
}, []);
const verifyAndPerform = useCallback(actions => {
if (verify(actions)) {
perform();
} else {
revoke();
}
}, [verify, perform, revoke]);
useEffect(() => {
if (handler !== handlerRef.current) {
revoke();
handlerRef.current = handler;
}
}, [handler, revoke]);
return {
verifyAndPerform
};
};
export { useCondition, useConditional };
//# sourceMappingURL=react-conditional.esm.js.map