4つの方法でpropsを受け取ってみる
はじめに
ReactとTypeScriptを勉強している中で、propsの受け取り方や型定義の定義があいまいだったので整理してみました。
実践
準備
create-react-appを使用してReact環境の構築は完了している前提で進めます。
まず、srcフォルダ下に「index.tsx」「TodoList.tsx(親コンポーネントのファイル)」「Todoitem.tsx(子コンポーネントのファイル)」のファイルを作成して、「index.tsx」「TodoList.tsx」には以下のコードを書きます。
import { StrictMode } from "react";
import * as ReactDOMClient from "react-dom/client";
import { TodoLists } from "./TodoLists";
const rootElement = document.getElementById("root");
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<>
<h1>Todo</h1>
<TodoLists />
</>
</StrictMode>
);
import { TodoItem } from "./TodoItem";
//todosオブジェクトの型を定義
export type Todo = {
id: number;
title: string;
};
export const TodoLists = () => {
const todos: Todo[] = [
{
id: 1,
title: "task1"
},
{
id: 2,
title: "task2"
},
{
id: 3,
title: "task3"
}
];
//TodoItemにtodosオブジェクトを渡す。
return <TodoItem todos={todos}></TodoItem>;
};
propsを受け取る
propsの受け取り方としては、
- 子コンポーネントに該当するファイル内で型エイリアス(またはインターフェース)を書くかどうか
- propsの受け取り方を分割代入するかどうか
で引数の書き方は変わってくると思います。したがって、書き方としては4種類あります。
①型エイリアスを書かない&propsを分割代入しない
まずはシンプルに、型エイリアスを書かずにpropsを書いてみます。
propsはオブジェクトなので、{ todos: Todo[] }と型定義します。
import { Todo } from "./TodoLists";
export const TodoItem = (props: {todos:Todo[]}) => {
return (
<>
<ul>
{todos.map((todo) => {
return <li key={props.todo.id.toString()}>{props.todo.title}</li>;
})}
</ul>
</>
);
};
こんな感じで描画されると思います。
シンプルですが、この方法はTodoItemコンポーネント内で受けとったpropsを使うときに、必ず値の前にpropsを書かないといけません。
②型エイリアスを書かない&propsを分割代入する
分割代入することで値の前にpropsを記載する必要はなくなりコード量も減ります。
import { Todo } from "./TodoLists";
export const TodoItem = ({ todos }: { todos: Todo[] }) => {
return (
<>
<ul>
{todos.map((todo) => {
return <li key={todo.id.toString()}>{todo.title}</li>;
})}
</ul>
</>
);
};
propsを受け取る値が増えると、型定義するコードも増えて引数のコード量が増えて可読性が落ちると思います。
③型エイリアスを書く&propsを分割代入する
型エイリアスを書くことでTodoItemコンポーネントの引数が増えても、型定義ではPropsを書くだけです。
import { Todo } from "./TodoLists";
type Props = {
todos: Todo[];
};
export const TodoItem = ({ todos }: Props) => {
return (
<>
<ul>
{todos.map((todo) => {
return <li key={todo.id.toString()}>{todo.title}</li>;
})}
</ul>
</>
);
};
④型エイリアスを書く&propsを分割代入する
一応、子コンポーネントで型エイリアスを書く&propsを分割代入しない方法も紹介します。
import { Todo } from "./TodoLists";
type Props = {
todos: Todo[];
};
export const TodoItem = (props: Props) => {
return (
<>
<ul>
{props.todos.map((todo) => {
return <li key={props.todo.id.toString()}>{props.todo.title}</li>;
})}
</ul>
</>
);
};
以上から、個人的にpropsの書き方は③がベストプラクティスかなと思います。
最後までお読みいただきありがとうございました。
気になる点などありましたら、コメントいただけると嬉しいです。
こちらにデモアプリを作成しました。
Discussion