LoginSignup
4
1

More than 1 year has passed since last update.

sort()メソッドを使ってReactでソート機能を実装する

Last updated at Posted at 2022-12-06

やりたいこと

お店の名前、評価のデータ一覧が入った配列が親コンポーネント<App>から渡され、 <ShopList> コンポーネントでmapを使ってさらに子供のコンポーネント<ShopItem>にデータ展開している。

この<ShopList> コンポーネントの中に、「並び替えボタン」を設置し、クリック時に評価順にソートして表示する機能を追加したい。

App.tsx
export type Shop = {
  name: string;
  rating: number;
};

const shops:Shop[] = [
  {
    name: 'shopA',
    rating: 1.2,
  },
  {
    name: 'shopB',
    rating: 2.6,
  },
  {
    name: 'shopC',
    rating: 0.9,
  },
  {
    name: 'shopD',
    rating: 3.1,
  },
];
const App = () => {
  return <ShopList shops={shops} />;
};
export default App;
ShopList.tsx
import { Shop } from './App'
import ShopItem from './ShopItem';


type Props = {
  shops: Shop[];
};

const ShopList = ({ shops }: Props) => {
  return (
    <>
      {shops.map((item, i) => (
        <ShopItem shop={item} key={i} />
      ))}
    </>
  );
};
export default ShopList;

実装方法

ShopList.tsx を以下のように修正する。

ShopList.tsx
import { useState, useEffect } from 'react';
import { Shop } from './App'
import ShopItem from './ShopItem';


type Props = {
  shops: Shop[];
};

const ShopList = ({ shops }: Props) => {
  const [sortedShops, setSortedShops] = useState<Shop[]>(shops);

  useEffect(() => {
    setSortedShops(shops);
  }, [shops]);

  const sortByRating = () => {
    var clonedShops = Array.from(sortedShops);
    clonedShops.sort((a, b) => b.rating - a.rating);
    setSortedShops(clonedShops);
  };

  return (
    <>
      <button onClick={sortByRating}>並び替えボタン</button>
      {sortedShops.map((item, i) => (
        <ShopItem shop={item} key={i} />
      ))}
    </>
  );
};
export default ShopList;

実装のポイント

  • useState()の初期値をuseEffect内で設定すること

useEffect内で setSortedShops を呼ぶことで、propsで受け取った値を sortedShops として設定することができる。React.useState()の初期値は一度しかセットされないため、useState()の初期値にpropsを使う場合はuseEffect()の中で値を設定することで、propsが変化した時に親から受け取ったshopsをsetすることでができる。

参考:【React】useState()の初期値にpropsを使う時の注意点

  • sortメソッドの結果を一時変数に入れる

sortメソッドを使ってお店の評価( rating )によるソートを行ったものを一時変数( clonedShops)に入れて、 setSortedShops することで、React側がオブジェクトの変更を検知し再レンダリングが走る。一時変数を使わず、直接 sortedShops をソートしようとすると、オブジェクトの変更が検知されず、再レンダリングが走らない。

4
1
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
4
1