反应:微调效果正在取消我的滚动效果

Posted

技术标签:

【中文标题】反应:微调效果正在取消我的滚动效果【英文标题】:React: spinner effect is canceling my scrolling effect 【发布时间】:2022-01-17 20:57:14 【问题描述】:

好的,伙计们,我是 React 的菜鸟,我知道我弄错了什么,但我看不出是什么。

我在我的页面之间放置了加载微调器,没有问题,直到这个页面:

所以我有一个在 X 轴上滚动的页面和一个在滚动过程中旋转的徽标,直到知道,一切都正常工作。还有没有加载微调器的代码:

import React,  useEffect, useRef  from "react";
import styled,  ThemeProvider  from "styled-components";
import  DarkTheme  from "./Themes";
import motion from 'framer-motion';
import LogoComponent from '../subComponents/LogoComponent';
import SocialIcons from '../subComponents/SocialIcons';
import PowerButton from '../subComponents/PowerButton';
import  Work  from '../data/WorkData';
import Card from "../subComponents/Card";
import  Umbrella  from "./AllSvgs";
import BigTitle from "../subComponents/BigTitle";

const Box = styled.div`
background-color: $props => props.theme.body;

height: 400vh;
position: relative;
display: flex;
align-items: center; 

`

const Main = styled(motion.ul)`
position: fixed;
top: 12rem;
left: calc(10rem + 15vw);
height: 40vh;
display: flex;

color: white;
` 

const Rotate = styled.span`
display: block;
position: fixed;
right: 1rem;
bottom: 1rem;
width: 80px;
height: 80px;
z-index:1;
`

// Framer-motion configuration

const container = 
    hidden: opacity:0,
    show: 
        opacity:1,

        transition: 
            staggerChildren:0.5,
            duration:0.5,
        
    



const WorkPage = () => 

    const ref = useRef(null);
    const umbrella = useRef(null);

    useEffect(() => 

            let element = ref.current;
            
            const rotate = () => 
                element.style.transform = `translateX($-window.scrollYpx)`
    
                umbrella.current.style.transform = `rotate(` + -window.scrollY + 'deg)'
            
    
            window.addEventListener('scroll', rotate)
    
            return () => window.removeEventListener('scroll', rotate)

    , [])


    return (
        <ThemeProvider theme=DarkTheme>

            <Box>
                <LogoComponent theme='dark'/>
                <SocialIcons theme='dark'/>
                <PowerButton />

                <Main ref=ref  variants=container initial='hidden' animate='show' >
                    
                        Work.map( d =>
                            <Card key=d.id data=d />
                        )
                    
                </Main>

                <Rotate ref=umbrella>
                    <Umbrella width=80 height=80 fill=DarkTheme.theme />
                </Rotate>

                <BigTitle text="PROJETS" top="10%" right="20%" />

            </Box>
            
        </ThemeProvider>
    )


export default WorkPage

然后我将代码与其他正在运行的页面具有相同的逻辑:

import React,  useEffect, useRef, useState  from "react";
import styled,  ThemeProvider  from "styled-components";
import  DarkTheme  from "./Themes";
import motion from 'framer-motion';
import RingLoader from "react-spinners/RingLoader";
import  css  from "@emotion/react";
import LogoComponent from '../subComponents/LogoComponent';
import SocialIcons from '../subComponents/SocialIcons';
import PowerButton from '../subComponents/PowerButton';
import  Work  from '../data/WorkData';
import Card from "../subComponents/Card";
import  Umbrella  from "./AllSvgs";
import BigTitle from "../subComponents/BigTitle";

const Box = styled.div`
background-color: $props => props.theme.body;

height: 400vh;
position: relative;
display: flex;
align-items: center; 

`

const Main = styled(motion.ul)`
position: fixed;
top: 12rem;
left: calc(10rem + 15vw);
height: 40vh;
display: flex;

color: white;
` 

const Rotate = styled.span`
display: block;
position: fixed;
right: 1rem;
bottom: 1rem;
width: 80px;
height: 80px;
z-index:1;
`

const override = css`
position: absolute;
bottom: 10%;
right: 10%;
`

// Framer-motion configuration

const container = 
    hidden: opacity:0,
    show: 
        opacity:1,

        transition: 
            staggerChildren:0.5,
            duration:0.5,
        
    



const WorkPage = () => 

    const [loading, setLoading] = useState(false);

    useEffect(() => 
            setLoading(true)
            setTimeout(() => 
                setLoading(false)
            , 2000)
            
    , [])

    const ref = useRef(null);
    const umbrella = useRef(null);

    useEffect(() => 

            let element = ref.current;
            
            const rotate = () => 
                element.style.transform = `translateX($-window.scrollYpx)`
    
                umbrella.current.style.transform = `rotate(` + -window.scrollY + 'deg)'
            
    
            window.addEventListener('scroll', rotate)
    
            return () => window.removeEventListener('scroll', rotate)

    , [])


    return (
        <ThemeProvider theme=DarkTheme>
            
                loading ?
                <RingLoader 
                color='#000' 
                loading=loading  
                size=60
                css=override
                />

                :

                <Box>
                    <LogoComponent theme='dark'/>
                    <SocialIcons theme='dark'/>
                    <PowerButton />

                    <Main ref=ref  variants=container initial='hidden' animate='show' >
                        
                            Work.map( d =>
                                <Card key=d.id data=d />
                            )
                        
                    </Main>

                    <Rotate ref=umbrella>
                        <Umbrella width=80 height=80 fill=DarkTheme.theme />
                    </Rotate>

                    <BigTitle text="PROJETS" top="10%" right="20%" />

                </Box>
            
        </ThemeProvider>
    )


export default WorkPage

而且滚动不再起作用了。徽标仍在旋转。我试图提出条件,但没有。 将 useState 设置为 true,但随后我在旋转功能上出现错误:

TypeError: Cannot read properties of null (reading 'style')
rotate
src/components/WorkPage.js:89
  86 |         let element = ref.current;
  87 |         
  88 |         const rotate = () => 
> 89 |             element.style.transform = `translateX($-window.scrollYpx)`
     | ^  90 | 
  91 |             umbrella.current.style.transform = `rotate(` + -window.scrollY + 'deg)'
  92 |         

我看不出我错过了什么...谢谢你们????

【问题讨论】:

【参考方案1】:

在您的第二个示例代码中(您在 useState 钩子中添加了 loadingsetLoading),&lt;Box&gt; 组件(包含 &lt;Main ref=ref... 组件)在 loading 时不会被渲染设置为true(您在第一个useEffect 中将其设置为true)。

由于&lt;Main ref=ref... 组件没有被渲染,let element = ref.current 行会将element 初始化为空。 (这就是您收到该错误的原因)

【讨论】:

好吧,这是有道理的。但是我把 setTimeout 在 2 秒后将其更改为 false,这就是为什么存在这种情况的原因,因为当加载器超时时,页面会加载。所有页面都显示良好,滚动时徽标在旋转,只是 scrollX 不起作用,因此页面是静态的 问题是包含let element = ref.current代码的useEffect函数第一次运行-> ref由于你的加载指示器将不存在。 一个建议是为您的loading 属性上的第二个useEffect 设置依赖关系。在第二个useEffect 内添加条件if 语句,以确保ref.current 不为空。 useEffect(() =&gt; if (ref.current !== null) // setup your scrolling listener here , [loading]) 伙计,你是个天才?? 我在思考逻辑,你做到了!谢谢它很好用,它将帮助我走向未来!

以上是关于反应:微调效果正在取消我的滚动效果的主要内容,如果未能解决你的问题,请参考以下文章

iCarousel 自动滚动效果

使用反应滚动浏览部分[重复]

如何在数据列表下拉列表中提供滚动效果?

Recyclerview cardview Onclick滚动时出现重复效果

如何取消tableView的footer的粘滞效果

在滚动视图内的 UIImageView 上捏缩放效果?