React Table の Cell の render 時に値を渡す
こんにちはフロントエンドエンジニアの茶木です。
React Table 便利ですよね。
今日は、React Table について知見が溜まったので共有します。特に Cellのアドバンスドな使い方についてです。
https://react-table-v7.tanstack.com/
まずuseTableと columnsの基本形を説明します。
useTable の基本形
const { rows, prepareRow } = useTable({
columns,
data,
});
return (
{rows.map((row, index) => {
prepareRow(row);
return (
<tr>
{row.cells.map((cell) => (<td>{cell.render("Cell")}</td>))}
</tr>
);
})}
);
useTable に columns(後述)と 表の列の値を持ったオブジェクトの配列であるdataを食わせると、取り回しやすい rows に変換してくれます。rowsを mapで回し、さらに、row.cells を mapで cell.renderとすることで、セルが描画されます。
columns の基本形
columns は表を作る際の下準備になります。
const columns = useMemo(
() => [
{
Cell: IdCell,
accessor: "id" as const,
},
{
Cell: DateCell,
accessor: "date" as const,
},
{
Cell: TextCell,
accessor: "text" as const,
},
]
);
accessor は dataの配列の要素の中のオブジェクトのキーと対応していて、cell.render 時に そのaccessor の値をキーとして、value を取得します。Cell は Reactコンポーネントか、Reactコンポーネントを出力するFunction です。
Cell内で value を整形して表示するのがセオリーです。
Cell に value 以外の値を渡すにはどうする?
表の内容であるvalueをセルに渡すのが、ここまでの話です。
実際は、セルには情報を表示するだけでなく、操作可能なボタンやセレクタやチェックボックスを仕込むケースもあります。その場合は専用のセルのReactコンポーネントを用意してセルの中だけで解決できるのがスマートですが、セルを含む列や表に対して影響を及ぼす操作をするケースもあります。
cell.render のオプションを使う
例えば、チェックボックスを持つセルで、チェックを入れると列をハイライトする機能を考えます。
まず、tr をコンポーネント化して、useState でハイライトかどうかの状態を持てるようにします。
const highlighter = useState(false);
const [highlight] = highlighter;
return (
<tr className={ highlight ? "highlight" : "normal"}>
{row.cells.map((cell) =>
(<td>{cell.render("Cell", {
highlighter
})}</td>)
)}
</tr>
);
実は cell.renderの第2引数に入れたものは render時にcolumns で指定した Cell の propsに渡るので、state とsetState 含めて渡しておけば、チェックボックスやボタンといった形で、外部操作が可能になります。
おわりに
cell.renderの第2引数に、操作用のメソッドを渡す方法悪くないと思うのですが、可能なものであればセル内であらかじめ準備したフックなどを使用してセル内で完結させる方法があるなら、それを試すべきと感じました。
React Table はかなり柔軟性の高いライブラリですが、TypeScriptの型指定やデータ構造が複雑になりがちなので、シンプルに考えて、コードをクリーンに保つように心がけたいです。
Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています
弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!
求人応募してみる!