How to prevent re-rendering when <Timeline /> playState changes?
I have defined my timeline as such:
const Component = () => {
const [playState, setPlayState] = useState(PlayState.pause);
return (
<Timeline
playState={playState}
labels={[{ label: 'start', position: 0 }]}
target={<Content />}
>
<Tweens />
</Timeline>
);
where <Content /> is a component using react-gsap targets.set to set targets similarly to what is done in the examples.
I want to control my timeline playState using useState inside my <Component /> which contains the <Timeline />.
But every time I change state <Content /> is re-rendered of course. The thing is my playState depends depends on <Content /> (I wait for some elements inside <Content /> to load, then I inform <Component /> that animation can begin and setPlayState(PlayState.play). Because of the re-rendering it is not possible because <Content /> stuff are reloaded, the animation begins before it has fully loaded.
I don't think this is currently possible due how react-gsap is structured because content is a rendered prop of <Timeline />. I understand this was done this way in order to be able to set the targets but IMO we should be able to separate content and animation in the React tree.
I tried to make it clear and I hope I am not doing anything too weird.
I ended up not using playState but using low-level GSAP to control timeline play state from content.
In order to do that I had to pass the <Timeline /> ref to <Content />. because of issue #33 I had to use a wrapper component.
import React, { useRef, forwardRef } from 'react';
import { Timeline, PlayState } from 'react-gsap';
import Content from './Content';
import Tweens from './Tweens';
const Component = () => {
const timelineRef = useRef(null);
const ContentWrapper = forwardRef<HTMLDivElement, {}>((props, targets: TargetsRef) => (
<Content targets={targets} timelineRef={timelineRef} />
));
return (
<Timeline
ref={timelineRef}
labels={[{ label: 'start', position: 0 }]}
target={<ContentWrapper />}
playState={PlayState.stop}
>
<Tweens />
</Timeline>
);
};
export default Component;
then in <Content /> I could access
const Content = ({ timelineRef: MutableRefObject<Timeline>, targets: TargetsRef }) => {
const handleClick = () => {
timelineRef.current?.getGSAP().play(0);
};
return <button ref={node => targets.set('button', node)} onClick={handleClick}>some content</button>
};