Search code examples
reactjsreact-spring

React-Spring transition 'leave' animation not working


When spring items leave the DOM nothing (no leave animation) happens.

Full CodeSandbox: https://codesandbox.io/s/jzz6xv1y4w

const Todo = ({ todo, onDeleteClick }) => {
  const transition = useTransition(todo, null, {
    from: { opacity: 0, transform: "translateY(-10px)" },
    enter: { opacity: 1, transform: "translateY(0)" },
    leave: { opacity: 0, transform: "translateY(10px)" }
  });
  return transition.map(
    ({ item, props, key }) =>
      item && (
        <TodoContainer style={props} key={key}>
          <span>{todo}</span>
          <button onClick={onDeleteClick}>X</button>
        </TodoContainer>
      )
  );
};

Solution

  • Move your transition to the app component. The transition should handle all the todos. This way it could control the enter and leave events.

    <div className="App">
      <h1>Todo App</h1>
      <input type="text" ref={ref} />
      <input type="submit" onClick={() => addTodo(ref.current.value)} />
      {/*  */}
      {transition.map(
        ({ item, props, key }, i) =>
          item && (
            <Todo
              transition={props}
              todo={item}
              onDeleteClick={() => deleteTodo(i)}
              key={key}
            />
          )
      )}
    </div>
    

    );

    The Todo component will be more simple:

    const Todo = ({ todo, onDeleteClick, transition }) => {
      return (
        <TodoContainer style={transition}>
          <span>{todo}</span>
          <button onClick={onDeleteClick}>X</button>
        </TodoContainer>
      );
    };
    

    Also make sure you provide an unique key for the transition. It helps to decide which component is entering and which is leaving. I used the todo text as the key in the example.

    This is the example: https://codesandbox.io/s/goofy-chaplygin-whvt4