I'm trying to get my head over React Spring. So I have some boxes, which I need to filter by an active index, and the idea is to animate the boxes rendering, but I'm only having an animation when the component renders the first time.
This is what I have so far:
import React from "react";
import ReactDOM from "react-dom";
import styled from "@emotion/styled";
import { useTransition, animated } from "react-spring";
import "./styles.css";
const Header = styled.div`
display: flex;
justify-content: center;
margin-bottom: 16px;
`;
const Content = styled.div`
display: flex;
justify-content: center;
`;
const Box = styled.div`
width: 64px;
height: 64px;
background-color: yellow;
border: 3px solid yellowgreen;
color: yellowgreen;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
`;
const EnhancedBox = animated(Box);
const App = () => {
const [activeBoxIndex, setActiveBoxIndex] = React.useState(0);
const boxes = [
{ label: "1", key: 0 },
{ label: "2", key: 1 },
{ label: "3", key: 2 }
];
const transition = useTransition(boxes, item => item.key, {
from: { maxHeight: "0px", overflow: "hidden", margin: "0px 0px" },
enter: { maxHeight: "100px", overflow: "hidden", margin: "5px 0px" },
leave: { maxHeight: "0px", overflow: "hidden", margin: "0px 0px" }
});
const handleBoxClick = n => () => {
setActiveBoxIndex(n);
};
return (
<div className="App">
<Header>
<button onClick={handleBoxClick(0)}>Show box 1</button>
<button onClick={handleBoxClick(1)}>Show box 2</button>
<button onClick={handleBoxClick(2)}>Show box 3</button>
</Header>
<Content>
{transition.map(({ item, props, key }) => {
return item.key === activeBoxIndex ? (
<EnhancedBox key={item.key} style={props}>
{item.label}
</EnhancedBox>
) : (
<></>
);
})}
</Content>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I set up a Code Sandbox project to make things easier. Any help would be much appreciated. https://codesandbox.io/s/wizardly-hill-6hkk9