useTransition立即挂载新对象

时间:2020-06-21 13:39:16

标签: reactjs react-spring

我正在尝试找出如何利用useTransition进行页面转换(简单的不透明度更改,其中首页淡出,新页面淡入)。

到目前为止,我正在进行这个小型演示https://codesandbox.io/s/sleepy-knuth-xe8e0?file=/src/App.js 它有点奏效,但很奇怪。当过渡开始时,新页面立即挂载,而旧页面开始制作动画。这会导致各种布局问题,而不是我所追求的行为。是否有可能让第一个元素淡出然后才安装并淡入第二个元素?

与演示相关的代码

import React, { useState } from "react";
import "./styles.css";
import { useTransition, a } from "react-spring";

export default function App() {
  const [initial, setInitial] = useState(true);
  const transition = useTransition(initial, {
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  });

  return (
    <div>
      {transition((style, initial) => {
        return initial ? (
          <a.h1 style={style}>Hello Initial</a.h1>
        ) : (
          <a.h1 style={style}>Hello Secondary</a.h1>
        );
      })}
      <button onClick={() => setInitial(prev => !prev)}>Change Page</button>
    </div>
  );
}

2 个答案:

答案 0 :(得分:1)

您可以通过等待离开动画完成来延迟过渡的开始。

const sleep = t => new Promise(res => setTimeout(res, t));

...

const transition = useTransition(initial, {
  from: { position: "absolute", opacity: 0 },
  enter: i => async next => {
    await sleep(1000);
    await next({ opacity: 1 });
  },
  leave: { opacity: 0 }
});

这也会在动画第一次运行时延迟动画。您可以通过ref来跟踪组件是否在之前渲染过,或者它是第一次渲染,然后如果是第一次渲染,则可以跳过sleep调用。

OR

您只需提供trail配置

const transition = useTransition(initial, {
    from: { position: "absolute", opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
    trail: 300
  });

答案 1 :(得分:0)

您需要添加position: absolute,然后需要使用CSS设置正确的位置。

import React, { useState } from "react";
import "./styles.css";
import { useTransition, a } from "react-spring";

export default function App() {
  const [initial, setInitial] = useState(true);
  const transition = useTransition(initial, {
    from: { position: 'absolute', opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  });

  return (
    <div>
      {transition((style, initial) => {
        return initial ? (
          <a.h1 style={style}>Hello Initial</a.h1>
        ) : (
          <a.h1 style={style}>Hello Secondary</a.h1>
        );
      })}
      <button onClick={() => setInitial(prev => !prev)}>Change Page</button>
    </div>
  );
}