概要
現在が参画しているプロジェクトではテーブルコンポーネントのベースとしてreact-bootstrap-table-nextを使っています。
ある日のタスクでテーブルの行の全選択と全解除を機能追加でつけることになりました。
一番楽なのはreact-bootstrap-table-nextの機能としてある行にチェックボックスをつけることです。
ただ、チェックボックスは小さいのと、クライアントが好んでいるのもボタンだったので
全選択/全解除ボタンを作ることにしました。
方針
全選択/全解除ボタンを押した時にtableコンポーネントに渡しているselectRowのonSelectAllを実行させる
実装
実際の業務のコードを抽象化したものです。
-
useAllSelectフックでtableコンポーネントへのrefと全選択/解除のための
ボタンコンポーネントを受け取り、tableRefをテーブルコンポーネントに渡す -
AllSelectButtonのonClickが発火されたら
tableRef?.current.selectionContext.handleAllRowsSelectが実行される
selectionContext.handleAllRowsSelectが内部でonSelectRowに渡しているonSelectAllを実行している
import React, { useRef } from "react";
import BootstrapTable from "react-bootstrap-table-next";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";
import { useAllSelect } from '../Hooks/AllSelect';
function App() {
// 全選択/解除を行うためのカスタムフック
const [tableRef, AllSelectButton] = useAllSelect();
const handleSelectAll = (isSelected) => {
// 全選択 or 全解除する時に行う処理
};
const columns = [
// Define your columns here
];
const data = [
// Your data here
];
const selectRow = {
mode: "checkbox",
hideSelectAll: true,
onSelectAll: handleSelectAll,
};
return (
<div>
<AllSelectButton allSelectButtonName={'全選択'} allUnSelectButtonName={'全解除'} />
<BootstrapTable
ref={tableRef}
keyField="id"
data={data}
columns={columns}
selectRow={selectRow}
/>
</div>
);
}
export default App;
import React, { memo, useRef } from 'react';
import Button from '../../../atoms/Button';
export function useAllSelect() {
const tableRef = useRef(null);
const handleAllUnSelect = (e) => {
tableRef?.current.selectionContext.handleAllRowsSelect(e, true);
};
const handleAllSelect = (e) => {
tableRef?.current.selectionContext.handleAllRowsSelect(e, false);
};
const AllSelectButton = memo(
({ color, allSelectButtonName = '全選択', allUnSelectButtonName = '全選択解除', ...props }) => (
<div className="mt-5 flex gap-x-5">
<Button color={'success'} onClick={(e) => handleAllUnSelect(e)}>
{allUnSelectButtonName}
</Button>
<Button color={'success'} onClick={(e) => handleAllSelect(e)}>
{allSelectButtonName}
</Button>
</div>
)
);
return [tableRef, AllSelectButton];
}
最後に
ドキュメントだけでなく、ソースを見ることは大事だと改めて感じました。
refを使って実行するのはすぐにわかるが、何が全選択を行うものなのかが
ドキュメントを見てもわからなかった、qiitaやzennにも参考になるようなものがなかった
(もしかして調べ方が悪いだけかも、、、笑)
内部のソースを見てようやくselectionContextにアクセスすればいけると分かった