如何在相同元素上组合 React-Spring useTrail 和 useTransition?

How to combine React-Spring useTrail and useTransition on same elements?

我有一个项目数组,在页面加载时使用 react-spring useTrail 挂钩在屏幕上显示动画。我想用 useTransition 挂钩动画移除这些项目,但我很难弄清楚如何实现它们。我不确定我是否应该将 useTransition 挂钩嵌套在我的 useTrail 中或相反?以下是相关的代码片段和 codesandbox:https://codesandbox.io/s/romantic-cartwright-v480o?file=/src/App.js

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

const habits = [
  { name: "Go to gym" },
  { name: "Meditate" },
  { name: "Practice guitar" }
];

export default function App() {
  const [habitsToShow, setHabitsToShow] = useState(habits);

  const trail = useTrail(habitsToShow.length, {
    from: {
      marginTop: -100,
      opacity: 0,
      transform: "translate3d(-150px,-40px,0)"
    },
    to: {
      marginTop: 0,
      opacity: 1,
      transform: "translate3d(0,0px,0)"
    }
  });

  const transitions = useTransition(habitsToShow, {
    from: {
      marginTop: -100,
      opacity: 0,
      transform: "translate3d(-150px,-40px,0)"
    },
    enter: {
      marginTop: 0,
      opacity: 1,
      transform: "translate3d(0,0px,0)"
    },
    leave: {
      marginTop: 0,
      opacity: 1,
      transform: "translate3d(-150px,-40px,0)"
    },
    // reverse: show,
    delay: 200
    // onRest: () => set(!show),
  });

  const handleRemove = (i) => {
    const newHabits = [...habitsToShow];
    newHabits.splice(i, 1);
    setHabitsToShow(newHabits);
  };

  return (
    <div
      className="App"
      style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
    >
      {trail.map((props, index) => {
       // useTransition hook here??
        return (
          <animated.div
            key={habitsToShow[index].name}
            style={{
              ...props,
              border: "1px solid black",
              width: "70%",
              marginTop: "5px",
              marginBottom: "5px"
            }}
            className="box"
          >
            <div key={habitsToShow[index].name}>
              <h1>{habitsToShow[index].name}</h1>
              <button onClick={(index) => handleRemove(index)}>Remove</button>
            </div>
          </animated.div>
        );
      })}
    </div>
  );
}

我认为您可以省略 useTrail 挂钩,而仅使用 useTransition 挂钩及其跟踪 属性。这样你只用一个钩子就可以达到同样的效果。我修复了删除调用,也修复了离开转换。

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

const habits = [
  { name: "Go to gym" },
  { name: "Meditate" },
  { name: "Practice guitar" }
];

export default function App() {
  const [habitsToShow, setHabitsToShow] = useState(habits);

  const transitions = useTransition(habitsToShow, {
    from: {
      marginTop: -100,
      opacity: 0,
      transform: "translate3d(-150px,-40px,0)"
    },
    enter: {
      marginTop: 0,
      opacity: 1,
      transform: "translate3d(0px,0px,0)"
    },
    leave: {
      marginTop: 0,
      opacity: 0,
      transform: "translate3d(-150px,-40px,0)"
    },
    // reverse: show,
    trail: 100
    // onRest: () => set(!show),
  });

  const handleRemove = (i) => {
    const newHabits = [...habitsToShow];
    newHabits.splice(i, 1);
    setHabitsToShow(newHabits);
  };

  return (
    <div
      className="App"
      style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
    >
      {transitions((props, item, state, index) => {
        return (
          <animated.div
            key={item.name}
            style={{
              ...props,
              border: "1px solid black",
              width: "70%",
              marginTop: "5px",
              marginBottom: "5px"
            }}
            className="box"
          >
            <div key={item.name}>
              <h1>{item.name}</h1>
              <button onClick={() => handleRemove(index)}>Remove</button>
            </div>
          </animated.div>
        );
      })}
    </div>
  );
}

https://codesandbox.io/s/usetransition-example-for-react-spring-my217