Reputation: 33
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>
)
);
};
Upvotes: 2
Views: 5812
Reputation: 8223
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
Upvotes: 3
Reputation: 5179
You have to render all your elements inside transition.map
. Now you render them outside of transition.map
by yourself, but wrap each element in transition.map
. Your Todo
elements are rendered and deleted here:
{todos.map((x, i) => (
<Todo todo={x} onDeleteClick={() => deleteTodo(i)} key={x} />
))}
But they have to be rendered on and deleted here:
return transition.map(
({ item, props, key }) => (
<TodoContainer style={props} key={key}>
<span>{item}</span>
<button onClick={onDeleteClick}>X</button>
</TodoContainer>
)
);
You need to change your component Todo
. It should render all items.
I create a working example for you: https://codesandbox.io/s/trusting-dewdney-jerxy
Upvotes: 0