react-springでスライドアニメーションを作りたい
Q&A
Closed
解決したいこと
表題の件、react-springでスライドアニメーションを実現したいです。
カードコンポーネントを初期表示時、useSpringを初期化していて、
ボタン押下時にスライドアニメーションを適用したいのですが、
最初にボタンを押下した時だけ、スライドが適用されずに位置だけが移動してしまいます。
2回目以降はしっかりとスライドされるので、hookや初期化が間違えている気がしているのですが、
ハマってしまっているので、何かご助言いただければ幸いです。
よろしくお願いします。
再現動画貼りたかったですが、Qiitaでは投稿できず、ソースのみ提供いたします。
ざっくりとした質疑で申し訳ないですが、ここ違うのでは?という箇所あれば
ご指摘いただきたいです。
該当するソースコード
function MatchCard({ user }) {
const [loading, setLoading] = useState(true);
const [currentIndex, setCurrentIndex] = useState(0); // カード枚数
const [liked, setLiked] = useState(null);
const [skipped, setSkipped] = useState(null);
// カードのアニメーション
const [cardStyles, setCardStyles] = useSpring(() => ({
transform: liked ? 'translateX(-100%)' : skipped ? 'translateX(100%)' : 'translateX(0)',
config: { tension: 80, friction: 20 },
}));
const handleLike = () => {
setLiked(true);
setSkipped(false);
// いいねの処理を追加する
nextCard();
};
const handleSkip = () => {
setSkipped(true);
setLiked(false);
// スキップの処理を追加する
nextCard();
};
const nextCard = () => {
setCurrentIndex(prevIndex => prevIndex + 1);
};
useEffect(() => {
setCardStyles({
transform: liked ? 'translateX(-100%)' : skipped ? 'translateX(100%)' : 'translateX(0)',
});
}, [liked, skipped, setCardStyles]);
useEffect(() => {
// データのロードが完了したらloadingをfalseに設定する
setLoading(false);
}, []);
useEffect(() => {
console.log(`いま表示しているカードの順番${currentIndex}`);
}, [currentIndex]);
if (loading) {
// データがロード中の場合、くるくるアニメーションを表示する
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '300px' }}>
<CircularProgress />
</div>
);
}
return (
<animated.div style={{...cardStyles, display: 'inline-block', width: '345px', height: '100%'}}>
{/* <div style={{ display: 'inline-block', width: '345px', height: '100%' }}> */}
<Card sx={{ maxWidth: 345 }}>
<CardMedia
component="img"
height="140"
image={user.imageUrl}
alt={user.name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div" noWrap>
{user.name}
</Typography>
<Typography variant="body2" color="text.secondary" noWrap>
{user.description}
</Typography>
</CardContent>
<ButtonGroup fullWidth variant="contained">
<Button sx={{ flexGrow: 1 }} color="primary" onClick={handleLike} disabled={liked}>Like</Button>
<Button sx={{ flexGrow: 1 }} color="secondary" onClick={handleSkip} disabled={skipped}>Skip</Button>
</ButtonGroup>
</Card>
{/* </div> */}
</animated.div>
);
}
export default MatchCard;
0