Well consider I have a set of components, these components all have some basic fields. An example may be a pop up that shows in case of an erroneous state.
This leads to something like:
function MyComponent(props) {
const [showErr, setShowErr] = React.useState(false);
const [errMsg, setErrMsg] = React.useState('');
return <>
<...>
<SomePopup
open={showErr}
errMsg={errMsg}
/>
</>
}
While this is trivial the settings might not be in case of more complex interactions with the rest of the component isn't. It's also unnecessary boilerplate and violates DRY.
The states can of course be combined in a custom hook useError
(or in this trivial case in a single state). However can I also make it so that whenever I declare an object to have useError
, it also has the component set up?
That way I could prevent erros like "forgetting the popup" and "forgetting to set useError state" - DRY errors.
Instead of a hook, consider the following higher-order component definition:
function withSomePopup(MyComponent) {
return function MyComponentWithSomePopup(props) {
const [showErr, setShowErr] = React.useState(false);
const [errMsg, setErrMsg] = React.useState('');
const propsWithSomePopup = React.useMemo(() => ({
...props,
setShowErr,
setErrMsg
}), [props, setShowErr, setErrMsg]);
return (
<>
<MyComponent {...propsWithSomePopup} />
<SomePopup open={showErr} errMsg={errMsg} />
</>
);
};
}
Then you can wrap your component like this:
export default withSomePopup(function MyComponent(props) {
const { setShowErr, setErrMsg } = props;
return (
<...>
);
});