来自 react-spring 的动画在 visibility-sensor 和 useEffect 下触发得太快

Animation from react-spring fires off too fast with visibility-sensor and useEffect

我有包装器 React 组件,它使用 react-spring 和 visibility-sensor 使其 children 从右侧淡入并将不透明度从 0 更改为 1。 useEffect 和 useState 都使孩子在第一次滚动后只出现一次。

问题是动画显示速度太快 - 没有从右侧到结束位置的 50px 的转换。 Image/text - 组件 children 在我滚动时弹出。

这是此组件的代码:

import React, { useEffect, useState } from 'react';
import { Spring, config } from 'react-spring/renderprops';
import VisibilitySensor from 'react-visibility-sensor';

export const FadeInContainer = ({
 children
}: any) => {
 const [isVisible, setVisibility] = useState(false);
 const [entered, setEntered] = useState(false);

 const onChange = (visiblity: any) => {
  setTimeout(() => {
   setVisibility(visiblity);
  }, 200);
 };

 useEffect(() => {
  if (isVisible) {
   setEntered(true);
  }
 }, [isVisible]);

 const FadeInDirection = () => {
  return (
   <Spring
    delay={500}
    config={config.slow}
    to={{
     opacity: entered ? 1 : 0,
     transform: entered ? 'translateY(0)' : 'translateY(50px)'
    }}
   >
    {({ opacity, transform }) => (
     <div style={{ opacity, transform }}>{children}</div>
    )}
   </Spring>
  );
 };

 return (
  <VisibilitySensor onChange={onChange}>
   <FadeInDirection />
  </VisibilitySensor>
 );
};

我已经尝试过的: 1、useEffect添加setTimeouts,onChange定义同上。 2. 尝试为能见度传感器添加 scrollDelay,如下所示:

  <VisibilitySensor onChange={onChange} scrollDelay={300}>

只滚动一次的解决方案来自这个帖子:

你知道是否可以做些什么来使滚动时只发生一次的动画更流畅(主要是变换)?

我认为问题是动画不工作。它只是在没有动画的情况下将不透明度从 0 切换到 1。我将它更改为基于钩子的动画并且它只是工作(仅当 useSpring 在 FadeInDirection 组件之外时)。 所以最初的问题是,FadeInDirection 定义在 FadeInContainer 里面,它没有自己的属性。它在每次渲染时都被重新定义。

创建 FadeInDirection 作为单独的组件。

我也取消了useEffect,我只在VisibilitySensor onChange return true时设置可见。

import React, { useState } from "react";
import { useSpring, animated } from "react-spring";
import VisibilitySensor from "react-visibility-sensor";

const FadeInDirection = ({ isVisible, children }) => {
  const props = useSpring({
    opacity: isVisible ? 1 : 0,
    transform: isVisible ? "translateY(0px)" : "translateY(50px)"
  });
  return <animated.div style={props}>{children}</animated.div>;
};

export const FadeInContainer = ({ children }) => {
  const [isVisible, setVisibility] = useState(false);

  const onChange = visiblity => {
    visiblity && setVisibility(visiblity);
  };

  return (
    <VisibilitySensor onChange={onChange}>
      <FadeInDirection isVisible={isVisible}>{children}</FadeInDirection>
    </VisibilitySensor>
  );
};

这里有一个例子:https://codesandbox.io/s/magical-sun-oqv0v?file=/src/App.js:184-787