最近は、もっぱらNext.js + styled-componentsでウェブサイトを作っております。
そんな折、動作原理を考えたら当然の挙動なのですが、一瞬ハマったのでメモを残します。
ことの発端
const BtnWrapper = styled.div` position: relative; width: 44px; height: 44px; background: red; transition: background .4s ease-in-out; &[data-is-select="true"] { background: blue; } `;
こんな感じのコードを書きまして、PropsでisSelectを渡して状態を切り替えようとしていたのですが、
import styled from 'styled-components'; export default function Btn({ isSelect }: { isSelect: boolean; }) { const BtnWrapper = styled.div` position: relative; width: 44px; height: 44px; background: red; transition: background .4s ease-in-out; &[data-is-select="true"] { background: blue; } `; return ( <Wrapper data-is-select={ String(isSelect) } className="btn-menu" /> ) }
こんな感じで書くと、CSSアニメーションが効きませんでした。
「あれ?backgroundってアニメーションできなかったかな?」と思い、ディベロッパーツール経由でdata属性を付けたり消したりすると、しっかりアニメーションします。
原因
styled-componentsをfunctionの中で定義しているのが原因です。
functionの中は再レンダリングが走った際に実行されてしまうので。
なので、CSSアニメーションを有効にしたい場合は、
import styled from 'styled-components'; const BtnWrapper = styled.div` position: relative; width: 44px; height: 44px; background: red; transition: background .4s ease-in-out; &[data-is-select="true"] { background: blue; } `; export default function Btn({ isSelect }: { isSelect: boolean; }) { return ( <Wrapper data-is-select={ String(isSelect) } className="btn-menu" /> ) }
という感じで、functionの外で定義してあげましょう。
的なことがissueに書いてありました。