skip to Main Content

I am new to react. This is a generated code block in my project by create-react-app

const container = document.getElementById("root");
const root = createRoot(container);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Now I am using gsap to render anime. There is a disgusting blank block at the top of the page. Finally I found out the reason is these code, I also find out the solutions, but I do not know why.

1. ReactDOM.render with <React.StrictMode> success.
2. createRoot.render(<App />) success.
3. createRoot.render() with <React.StrictMode> FAILED.

Here is the project
Can anyone explain these differences?

———Edit———–
context is a solution, but it’s broken again after add another <div id='img2'> for animation

2

Answers


  1. Chosen as BEST ANSWER

    Should use ScrollTrigger in this way

        const main = useRef(null);
        const tl = useRef()
    
        useLayoutEffect(() => {
            let ctx = gsap.context(() => {
                tl.current = gsap.timeline({
                    scrollTrigger: {
                        trigger: '.screen1',
                        start: 'top top',
                        end: '+=200',
                        scrub: true,
                        pin: true,
                        markers: true,
                    }
                })
                    .fromTo(
                        '#img1',
                        {
                            opacity: 0,
                            x: 0
                        },
                        {
                            opacity: 1,
                            x: '20%',
                        })
                    .fromTo(
                        '#img2',
                        {
                            opacity: 0,
                            x: '100%' 
                        },
                        {
                            opacity: 1,
                            x: '80%',
    
                        })
            }, main);
            return () => ctx.revert();
        }, [])
    

  2. From the gsap.context() documentation:

    gsap.context() works around the React 18 "double-call of useEffect() in Strict Mode" issue that normally breaks from() logic – just call revert() on the Context in your useEffect() cleanup function:

    import { gsap } from 'gsap';
    import { ScrollTrigger } from 'gsap/ScrollTrigger';
    import React, { useEffect, useRef } from 'react';
    import './App.css';
    gsap.registerPlugin(ScrollTrigger);
    
    function App() {
        const ref = useRef(null);
    
        useEffect(() => {
            const ele = ref.current;
            let ctx = gsap.context(() => {
                gsap.fromTo(
                    ele.querySelector('#img1'),
                    {
                        opacity: 0,
                        x: -100,
                    },
                    {
                        opacity: 1,
                        x: 100,
                        scrollTrigger: {
                            trigger: ele.querySelector('.screen1'),
                            start: 'top top',
                            end: 'bottom center',
                            scrub: true,
                            pin: true,
                            markers: true,
                        },
                    },
                );
            });
            return () => ctx.revert();
        }, []);
    
        return (
            <div ref={ref}>
                <div className="screen1">
                    <div id="img1">load img</div>
                </div>
                <div className="screen2"></div>
                <div className="screen3"></div>
                <div className="screen4"></div>
            </div>
        );
    }
    
    export default App;
    

    codesandbox

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search