React 全然わからないので、『すべてがネコになる』を実現することを目標に、ひとまずマウスオーバーした文字列をネコにしていく所業を行えるようにします。
まずはこれを見てください。
このように触れたものをネコに変更する実装を行いました。
実装と言っても単純に functional component を使って、文字列を任意の値に変更して返すだけです。
src/components/Nyanize.tsx
import React, { useEffect, useState, useRef, createRef } from 'react';
// デフォルトで置き換え文字列を `🐈` にします。ネコ関連の emoji は異常に多いので、
// コンポーネントを使用する側で任意に置き換え文字列を変更できるようにします。
const nyanize = (text: string, cat = '🐈'): JSX.Element[] => {
const splittedText = text.split('');
// 文字列は任意の字数を取るので、文字数分だけ要素の ref を割り当てるられるように、
// Ref を確保しておきます。
const refs = [...Array(text.length)].map(_ => useRef<HTMLSpanElement>());
const [elementChars, setElementChars] = useState<string[]>([]);
// マウスオーバーしたらとにかくネコに置き換えます。
const onMouseOverHandler = (index: number): void => {
elementChars[index] = cat;
setElementChars(elementChars);
};
// 効率の良いやり方ではなさそう
refs.current.forEach((ref, index) => {
useEffect(() => {
setElementChars(c => c.concat(splittedText[index]));
if (ref.current) {
ref.current.addEventListener(
'mouseover',
onMouseOverHandler.bind(null, index)
);
return (): void => {
ref.current.removeEventListener(
'mouseout',
onMouseOverHandler.bind(null, index)
);
};
}
}, [ref.current]);
});
return splittedText.map((_, index) => (
<span ref={refs.current[index]} key={index}>
{elementChars[index]}
</span>
));
};
export default nyanize;
使う側はこんな感じです。
// 省略
import nyanize from './Nyanize';
// 省略
const PostList: React.FC = () => {
// nyanize に任意の文字列を渡す
return <div>{nyanize('foobarbaz')}</div>;
};
おわり。
Image by Petra Bajusová from Pixabay
Weekly number of page views since last build: 🥰