1

I have an array of items that animate to the screen with react-spring useTrail hook when the page loads. I would like to animate the removing of these items with useTransition hook but I have hard time figuring out how to implement both of them. I'm not sure if I should nest the useTransition hook inside of my useTrail or the other way around? Here are the relevant code snippets and 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>
  );
}

1 Answers1

1

I think you can leave out the useTrail hook and use only the useTransition hook with its trail property. This way you can achieve the same effect with only one hook. I fixed the remove call, and the leave transition also.

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

Peter Ambruzs
  • 7,763
  • 3
  • 30
  • 36