0.1.0 • Published 2 years ago
react-use-controls v0.1.0
useControls - a React Hook to imperativelly control the state of child compoenets.
This hook is very useful for time-based tasks (animation components, etc...) when a parent component needs to control child state and do some repeatful operations in a non-declarative way.
Simple Use
import {
useControls,
useSetControls,
ControlledChildProps,
} from "react-use-controls";
interface ChildControls {
setMessage: (message: string) => void;
message: string;
}
const Parent = () => {
const childControls = useControls<ChildControls>();
return (
<>
<button
onClick={() =>
childControls.do((controls) => controls.setMessage("Welcome!"))
}
>
Change Child Message From Parent
</button>
<Child controls={childControls} />
</>
);
};
interface ChildProps extends ControlledChildProps {
// Other Child Props...
}
const Child = (props: ChildProps) => {
// Gets props.controls and give you a function to set any control you want.
const [setControls] = useSetControls(props);
// This is a custom state which we use to set as two controls.
const [message, setMessage] = useState("Learn React");
// Use an effect or more to set all child controls.
useEffect(() => {
setControls({ setMessage, message });
}, [setControls, setMessage, message]);
return <p>{message}</p>;
};
Listeners
Listeners help to detect child state changes in parent component.
This is useful when you want to use a child state value in parent and you want to sync them to be the same in two parnet and child.
import {
useControls,
useSetControls,
ControlledChildProps,
} from "react-use-controls";
interface ChildControls {
setMessage: (message: string) => void;
message: string;
}
const Parent = () => {
const childControls = useControls<ChildControls>({
listen: {
message: (value, prevValue, forceUpdate) => {
if (value !== prevValue) {
// This will force Parent component to update every time the message state is changed from child.
forceUpdate();
}
}
},
});
return (
<>
<button
onClick={() =>
childControls.do((controls) => controls.setMessage("Welcome!"))
}
>
Change Child Message From Parent
</button>
Message In Child: <Child controls={childControls} />
Message Used In Parent: <h2>{childControls.controls.message}</h2>
</>
);
};
- You Could use
listen: { message: true }
instead of the method above to automatically force update on every change. - The Parent component above does not display
message
value on first render (mount phase
). you can use the following effect to show the message when mounted.
React.useEffect(childControls.forceUpdate, []);
0.1.0
2 years ago