7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Material-UI テーブル内の行を検索でフィルターする

Posted at

初めに

この記事では以下のように検索バーに文字を入力すると、テーブルの行をフィルターするコンポーネントについて書きました。

2022-05-03_07h32_02.gif

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&nbsp;(g)</TableCell>
            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
            <TableCell align="right">Protein&nbsp;(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&nbsp;(g)</TableCell>
            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
            <TableCell align="right">Protein&nbsp;(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);
  };

参考記事

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?