概要
本当はcssでやったほうがパフォーマンスはいいと思いますが、ちょっと面倒だったのでカスタムフックを用意してちゃちゃっと実装してみました。
完成形
コード
// カスタムフック
const useDelayText = (delay, time, text) => {
const [resultText, setResultText] = useState('');
// 無限ループに入っちゃうので、useEffectで制御
useEffect(() => {
// 1文字ずつの表示時間を計算
const showIntervalTime = time / text.length;
for (let index = 0; index < text.length; index++) {
// 表示したい文字をスライス
const t = text.slice(0, index + 1);
// delayさせたいので、外側でsetTimeoutを入れる
setTimeout(() => {
// それぞれの文字数ごとにsetTimeoutでスライスした結果をsetしていく
setTimeout(() => setResultText(t), showIntervalTime * (index + 1));
}, [delay])
}
}, []);
return resultText;
}
// 使い方
const First = memo(() => {
const yusou = useDelayText(0, 1000, '車の輸送');
const tax = useDelayText(1000, 1000, '税込価格');
const sijou = useDelayText(2000, 1000, '市場最安値');
return (
<div className={styles.fv}>
<p>{yusou}</p>
<p className={styles.fv_yellow}>{tax}</p>
<p className={styles.fv_red}>{sijou}</p>
</div>
)
});
工夫点
はじめはdelayさせる予定はなかったんだけど、delayさせないと同時に文字出てくるわーってなりました。
そこで、delay用の引数をまずは用意して、そこからどうしようかなーって10秒ぐらい眺めていたら、
「もう1個外側に大きくsetTimeoutで囲えばよくね?」ってなってやってみたらうまく動きました。
感想
汎用的に使えるかわかりませんし、cssで実装したほうがパフォーマンスはいいと思います。
そんなにパフォーマンスも意識せず、少ない文字数であればこっちでもいいかなーって気がしているので、
使ってみよう!って思って暗たらうれしいです!(LGTMおまちしてます)