-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add useCssTransitionGroup hook #479
Comments
I assume you meant const [transitionRef, transitionClassName] = useCssTransition({ in: isVisible, classNames: 'button' }) That way it will be easier to create multiple transitions because array destructuring makes it easier to name variables differently so they don't clash (which I assume is why I'll put a pin in this idea and come back to it later, thanks for the suggestion and feel free to discuss further. |
Oh yes you are absolutely right - Maybe it would also have a third return value to support the mounted/unmount feature:
And yes - the array syntax is probably better here - className is a quite often used variable and maybe you would even like to add two animations at the same time. |
Hello, Please forgive me for this little aside, but still related to using hooks to set a classname after on a component lifecycle event. I came a few times to look at the features of React Transition Group but I've always found a workaround and avoided adding it to the project dependency. Now that React hooks are stable and I have a project involving animations that require this kind of features, I tried to implement a custom hook https://codepen.io/creative-wave/pen/vMRRWd My hook has serious limitations. The features exposed in your comments are also very nice. But this proof of concept seems ok for my current project and I was just wondering why React Transition Group is using a node reference to force a reflow. It's not easy to debug through setTimeout callbacks, but it seems that they are called in the right order in my tests. Do you have some insights to give me or links to look at on this topic? EDIT: comments from this PR was helpfull. I've also been able to see why a reflow might be seen as necessary, but an easy workaround is to make |
I rewrite Use Example:const duration = 300;
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
};
const transitionStyles = {
entering: { opacity: 1 },
entered: { opacity: 1 },
exiting: { opacity: 0 },
exited: { opacity: 0 },
};
function FadeExample({ show, ...other }) {
const [status, unmounted, nodeRef] = useTransition<HTMLDivElement>({ in: show, timeout: duration, unmountOnExit: true });
if (unmounted) return null;
return (
<div
{...other}
ref={nodeRef}
style={{ ...defaultStyle, ...transitionStyles[status] }}
/>
);
} |
@chilbi Ah that’s amazing, was looking for exactly that just now! Would love to see this merged into the library. |
@chilbi that's a quite complex solution for people looking for an easy way to animate mounting component, I mean it's working, but is a deep dig code to follow. still big up for your commitment |
So, can we expect to see hooks integrated into the library any time soon? |
Hopefully soonish 😜 I'll start working on improving our test suite, then I'll see what to do from there, I also want to resolve #623, but maybe these will happen simultaneously. |
I might be oversimplifying things, but I think this basic hook is enough: enum TransitionStage {
entering = 'entering',
entered = 'entered',
exiting = 'exiting',
exited = 'exited',
appear = 'appear',
}
export function useInOutTransition(value: boolean, duration: number) {
const [state, setState] = useState(value ? TransitionStage.appear : TransitionStage.exited);
const isInitialRun = useRef(true);
const durationRef = useRef(duration);
durationRef.current = duration; // use latest
useEffect(() => {
if (isInitialRun.current) {
isInitialRun.current = false;
return () => {};
}
setState(value ? TransitionStage.entering : TransitionStage.exiting);
const tmId = setTimeout(() => {
const next = value ? TransitionStage.entered : TransitionStage.exited;
setState(next);
}, durationRef.current);
return () => {
if (tmId) clearTimeout(tmId);
};
}, [value]);
return state;
}
|
Now that react supports hooks you might add one to this project e.g. like this:
This would allow people to wrap the library hook with a special behaviour based on their project requirements like this:
const useSlideIn = ({in}) => useCssTransitionGroup({in, classNames: 'slide'});
or
const useSlideIn = ({in}) => useCssTransitionGroup({onEnter: () => /* special slide logic */, in, classNames: 'slide'})
And then reuse such a transition effect multiple times in the project:
The text was updated successfully, but these errors were encountered: