1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】props多すぎ問題を解決したい

Posted at

はじめに

個人で作ったプロジェクトのコンポーネント分割を行っていたところ、propsを10個以上定義する必要がありました。
コンポーネント分割したもののpropsが多く、解決方法はないか調べたことをまとめてみました。

問題

コンポーネント分割した際にpropsが多くなる

App.tsx
  return (
    <>
          <Search
            getData={getData}
            additivesSearch={additivesSearch}
            isDetailedFilterOpen={isDetailedFilterOpen}
            setIsDetailedFilterOpen={setIsDetailedFilterOpen}
            handleSubmit={handleSubmit}
            register={register}
            setValue={setValue}
            resetField={resetField}
            onAdditivesSubmit={onAdditivesSubmit}
            handleReset={() => handleReset(true)}
          />
    </>
  );
}

解決方法

1.オブジェクトにまとめ、スプレッド構文{...オブジェクト名}を使って設定する

App.tsx
const searchProps = {
  getData: getData,
  additivesSearch: additivesSearch,
  isDetailedFilterOpen: isDetailedFilterOpen,
  setIsDetailedFilterOpen: setIsDetailedFilterOpen,
  handleSubmit: handleSubmit,
  register: register,
  setValue: setValue,
  resetField: resetField,
  onAdditivesSubmit: onAdditivesSubmit,
  handleReset: () => handleReset(true)
};

// 省略

  return (
    <>
      <Search {...searchProps} />
    </>
  );
}

MDNより引用

スプレッド (...) 構文を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数(関数呼び出しの場合)や要素(配列リテラルの場合)を目的の場所に展開することができます。

スプレッド構文で、オブジェクト内のプロパティを一つずつ展開できると理解しました。

2.Custom Hooksを使う

1の方法は<Search {...searchProps} />で指定することで、すっきりしましたが、propsの指定が多いことには変わりがありません。

App.tsxに定義していたSearchコンポーネント関連するものをuseSearchFormとしてCustomHooks化しました。
⇒Searchコンポーネント内に定義することと同じかと思いましたが、再利用できるため、カスタムフック化してみました。

useSearchForm.ts
import { useForm, type SubmitHandler } from "react-hook-form";
import type { AdditivesSearch } from "../domain/AdditivesSearch";

export const useSearchForm = (
  additivesSearch: (formData: AdditivesSearch) => Promise<void>
) => {
  const { handleSubmit, register, setValue, resetField } =
    useForm<AdditivesSearch>();

  const onAdditivesSubmit: SubmitHandler<AdditivesSearch> = (formData) => {
    if (formData.have_additives === "0") {
      formData.additives = "";
      formData.additivesWord = "";
    }
    additivesSearch(formData);
  };

  const handleReset = (have_additives_rest: boolean) => {
    resetField("sake_name");
    if (have_additives_rest) {
      setValue("have_additives", "");
    }
    resetField("additives");
    resetField("additivesWord");
    resetField("maker");
  };

  return {
    handleSubmit,
    register,
    setValue,
    resetField,
    onAdditivesSubmit,
    handleReset,
  };
};

App.tsx
import { useSearchForm } from "./hooks/useSearchForm.ts";

const searchForm = useSearchForm(additivesSearch);

const searchProps = {
    getData,
    additivesSearch,
    isDetailedFilterOpen,
    setIsDetailedFilterOpen,
    ...searchForm,
    handleReset: () => handleReset(true),
};

// 省略

  return (
    <>
      <Search {...searchProps} />
    </>
  );
}

おわりに

スプレッド構文は配列のコピー、要素の追加で使うものと思っていましたが、オブジェクトでも使用できることがわかりました。
コンポーネントの分割することで、役割分担できて見やすいと思う一方で、分割するのが難しいとも感じました。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?