初めに
この記事では以下のように検索バーに文字を入力すると、テーブルの行をフィルターするコンポーネントについて書きました。
Material-UI(MUI)は React 用のコンポーネントやアイコンなどを提供するライブラリです。
コード
App.js
import { useState } from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import Search from "./Search";
const createData = (name, calories, fat, carbs, protein) => {
return { name, calories, fat, carbs, protein };
};
// テーブルの行の初期値
const initialRows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9)
];
// テーブルを表示するコンポーネント
const BasicTable = (props) => {
const { rows } = props;
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
const App = () => {
// テーブルの行
const [rows, setRows] = useState([...initialRows]);
// 検索バーに入力された文字
const [searched, setSearched] = useState("");
return (
<div className="App">
<Search
initialRows={initialRows}
searched={searched}
setRows={setRows}
setSearched={setSearched}
/>
<BasicTable rows={rows} />
</div>
);
};
export default App;
Search
import SearchIcon from "@mui/icons-material/Search";
import TextField from "@mui/material/TextField";
// 検索バーのコンポーネント
const SearchMovie = (props) => {
const { searched, initialRows, setRows, setSearched } = props;
// 検索文字によってテーブルの行をフィルター関数
const requestSearch = (searchedVal) => {
const filteredRows = initialRows.filter((row) => {
return row.name.toLowerCase().includes(searchedVal.toLowerCase());
});
setRows(filteredRows);
};
// 検索バーの文字が変化したときにフィルターを実行する関数
const changeSearchedHandler = (event) => {
setSearched(event.target.value);
requestSearch(event.target.value);
};
return (
<div>
<SearchIcon />
<TextField
id="standard-basic"
label="Search"
variant="standard"
value={searched}
onChange={(event) => changeSearchedHandler(event)}
/>
</div>
);
};
export default SearchMovie;
index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
説明
テーブルの初期値を設定します。これは検索バーが空文字になったとき、テーブルの全データを表示するために設定しています。
// テーブルの行の初期値
const initialRows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9)
];
テーブルコンポーネントには行の state を渡しています。このようにすることでフィルター後の行のみをテーブルに表示することができます。
// テーブルを表示するコンポーネント
const BasicTable = (props) => {
const { rows } = props;
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
App
コンポーネントでテーブルの行と検索バーの文字の state を管理しています。それを子コンポーネントである Search
コンポーネント(検索バーの操作やフィルターを行うコンポーネント)と BasicTable
(テーブルを表示するコンポーネント)に渡します。
const App = () => {
// テーブルの行
const [rows, setRows] = useState([...initialRows]);
// 検索バーに入力された文字
const [searched, setSearched] = useState("");
return (
<div className="App">
<Search
initialRows={initialRows}
searched={searched}
setRows={setRows}
setSearched={setSearched}
/>
<BasicTable rows={rows} />
</div>
);
};
searchedVal
という引数で検索バーの文字を受け取り、その文字でテーブルの name
列をフィルターします。
// 検索文字によってテーブルの行をフィルター関数
const requestSearch = (searchedVal) => {
const filteredRows = initialRows.filter((row) => {
return row.name.toLowerCase().includes(searchedVal.toLowerCase());
});
setRows(filteredRows);
};
検索バーの文字が変化したときに、親コンポーネントの searched
という state と、フィルターを実行します。
// 検索バーの文字が変化したときにフィルターを実行する関数
const changeSearchedHandler = (event) => {
setSearched(event.target.value);
requestSearch(event.target.value);
};
参考記事