react-spring@next - пружина с асин c забавой c как 'to', анимирующая каждый рендер - PullRequest
0 голосов
/ 31 января 2020

Пружина реагирующей пружины (версия 9), значение «to» которой является асинхронной c, проходит цикл анимации при каждом повторном рендеринге. Если 'to' является простым объектом, анимация срабатывает только первоначально, как и ожидалось.

Рассмотрим этот компонент:

const Component = () => {
    // let's trigger some rerenders
    const [state, setState] = useState(false);
    useEffect(() => {
        setInterval(() => {
            setState(x => !x);
        }, 1000);
    }, []);

    // a spring with an async func provided to 'to'
    const props = useSpring({
        to: async (next, cancel) => {
            await next({opacity: 1, color: '#ffaaee'})
            await next({opacity: 0, color: 'rgb(14,26,19)'})
        },
        from: {opacity: 0, color: 'red'}
    });

    return <animated.div style={props}>I will fade in and out</animated.div>
};

Текст будет постоянно мигать.

Я считаю, что это не намеренное поведение. Это ошибка, или я делаю что-то не так?

1 Ответ

0 голосов
/ 31 января 2020

Я думаю, что предполагаемое поведение - показать текущее состояние свойства to для useSpring. Когда он постоянен, он всегда будет показывать одно и то же состояние при каждом рендере. Но вы можете поменять свойство на использование пружины. Например:

const ComponentColor = () => {
  const [color, setColor] = React.useState("red");

  const props = useSpring({
    to: { color },
    from: { color: "red" }
  });

  return (
    <>
      <animated.h2 style={props}>This color will change</animated.h2>
      <button onClick={() => setColor("blue")}>blue</button>
      <button onClick={() => setColor("green")}>green</button>
      <button onClick={() => setColor("orange")}>orange</button>
    </>
  );
};

В этом случае цвет текста изменится на цвет, который вы нажали. Я думаю, что ваш пример соответствует этому. При каждом рендеринге будет отображаться текущее состояние свойства to, являющегося последовательностью. Поэтому я думаю, что это предполагаемое поведение.

Если вы хотите, чтобы использовать анимацию состояния только при первом рендеринге. Затем вы можете реорганизовать анимационную часть в новый компонент и убедиться, что она будет отображаться только в первый раз. Например, если вы используете React.memo, он переопределяет компонент вашей функции только в случае изменения одного из его свойств. В этом примере отсутствует свойство, поэтому оно будет отображаться только в первый раз.

const Component = () => {
  // let's trigger some rerenders
  const [state, setState] = React.useState(false);
  React.useEffect(() => {
    setInterval(() => {
      setState(x => !x);
    }, 2000);
  }, []);

  return <FirstTimeAnimate />;
};

const FirstTimeAnimate = React.memo(() => {
  const props = useSpring({
    to: async (next, cancel) => {
      await next({ opacity: 0.25, color: "#black" });
      await next({ opacity: 1, color: "blue" });
    },
    from: { opacity: 0, color: "red" }
  });

  return <animated.h2 style={props}>I will fade in and out</animated.h2>;
});

https://codesandbox.io/s/fervent-margulis-drt5l

...