0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今回は他のコンポーネントに対して値を渡す方法、propsについて学習していきます。

同じコンポーネントを色違いで使いたい

第五回で作成したListコンポーネントを、色違いで2つ並べたいとします。

このためにList1.tsxList2.tsxを作ってコピペするのは、さすがに非効率です。そこで登場するのがpropsです。外から値を渡して内部で使えるようにすると、コンポーネントを簡単に使い回せるようになります。

まずは色のクラスをGreet.cssに追加しておきましょう。

/* Greet.css に追記 */
.red   { color: red; }
.blue  { color: blue; }
.green { color: green; }

propsの受け取り方

コンポーネントの引数にpropsを定義します。

//List.tsx
type ListProps = {
  color?: string;
}

const List = (props: ListProps)=> {
  console.log(props);
  return (
    <ul className="item-list">
      <li>item-1</li>
      <li>item-2</li>
      <li>item-3</li>
      <li>item-4</li>
      <li>item-5</li>
    </ul>
  );
}

export default List;

TSXで書いているので、引数には型が必要です。typeListPropsという型を宣言し、引数の後ろに: ListPropsと付けています。プロパティ名の後ろの?は「渡さなくてもよい」という意味です。

渡す側は、HTMLの属性と同じ書き方です。

//Greet.tsx
import "./Greet.css"
import List from "./List"
const Greet = ()=> {
  return (
    <div className="component">
      <h3>Hello World</h3>
      <List color="red" />
    </div>
  );
}

export default Greet;

コンソールを確認すると{ color: "red" }と表示されます。colorという属性名でredという値を設定すると、propsオブジェクトのcolorプロパティにredが入って渡ってきます。

型に無い属性を渡すとその場でエディタが教えてくれるので、そこはTSXの利点です。

渡した値を使ってみる

受け取った値をクラス名に使って、色を変えてみましょう。classNameを式にして、バッククォートで組み立てます。

//List.tsx
type ListProps = {
  color?: string;
}

const List = (props: ListProps)=> {
  return (
    <ul className={`item-list ${props.color}`}>
      <li>item-1</li>
      <li>item-2</li>
      <li>item-3</li>
      <li>item-4</li>
      <li>item-5</li>
    </ul>
  );
}

export default List;

classNameitem-list redになり、リストの文字が赤くなりました。

渡す値を変えるだけで見た目が変わるので、同じコンポーネントを使い回せます。

//Greet.tsx
import "./Greet.css"
import List from "./List"
const Greet = ()=> {
  return (
    <div className="component">
      <h3>Hello World</h3>
      <List color="blue" />
      <List color="red" />
    </div>
  );
}

export default Greet;

青と赤のリストが2つ並びました。

propsという名前は慣習

ここからは少しTypeScriptの話になります。

引数名のpropsは慣習的にそう書いているだけで、pなどでも問題なく動きます。

//List.tsx
const List = (p: ListProps)=> {
  return (
    <ul className={`item-list ${p.color}`}>
      ...
    </ul>
  );
}

文法的にはどちらでも同じ意味です。ただ読み手が混乱するので、素直にpropsにしておきましょう。

分割代入で書く

props.colorと毎回書くのは少し冗長です。propsはただのオブジェクトなので、分割代入で必要なプロパティだけ取り出せます。

//List.tsx
type ListProps = {
  color?: string;
}

const List = ({ color }: ListProps)=> {
  return (
    <ul className={`item-list ${color}`}>
      <li>item-1</li>
      <li>item-2</li>
      <li>item-3</li>
      <li>item-4</li>
      <li>item-5</li>
    </ul>
  );
}

export default List;

これはReactの機能ではなくTypeScript側の機能なので、混同しないように注意してください。

デフォルト値を設定する

分割代入では、値が渡されなかったときのデフォルト値を書けます。

//List.tsx
const List = ({ color = "green" }: ListProps)=> {
  return (
    <ul className={`item-list ${color}`}>
      ...
    </ul>
  );
}
//Greet.tsx
const Greet = ()=> {
  return (
    <div className="component">
      <h3>Hello World</h3>
      <List />
      <List color="red" />
    </div>
  );
}

colorを渡さなかったほうにはundefinedが入るため、初期値のgreenが使われて緑色になります。

別の名前で受け取る

受け取る側で名前を変えたいときは、コロンで指定します。

//List.tsx
const List = ({ color: c = "green" }: ListProps)=> {
  return (
    <ul className={`item-list ${c}`}>
      ...
    </ul>
  );
}

ここに設定する名前は何でも構いません。この関数の中ではcという名前でcolorの値が使えます。

propsの基本ルール

基本的にコンポーネントは、propsの値によってのみ出力結果が変わるように作ります。何か表示を変えたくなったときは、props経由で値を渡すのが一般的です。

確認問題

Listコンポーネントに、リストの見出しを表示する機能を追加します。

//List.tsx
type ListProps = {
  color?: string;
}

const List = ({ color = "green" }: ListProps)=> {
  return (
    <ul className={`item-list ${color}`}>
      <li>item-1</li>
      <li>item-2</li>
      <li>item-3</li>
    </ul>
  );
}

export default List;

問題

Listtitleというpropsを追加してください。条件は以下の通りです。

  1. titleは渡さなくてもよいものとする
  2. 渡されなかった場合はアイテム一覧と表示する
  3. ulタグの上にh3タグでtitleを表示する
  4. Greet.tsxからListを2つ読み込み、片方には買い物リストを渡し、もう片方は何も渡さない

(下に解答を記載しています)

解答

//List.tsx
type ListProps = {
  color?: string;
  title?: string;
}

const List = ({ color = "green", title = "アイテム一覧" }: ListProps)=> {
  return (
    <div>
      <h3>{title}</h3>
      <ul className={`item-list ${color}`}>
        <li>item-1</li>
        <li>item-2</li>
        <li>item-3</li>
      </ul>
    </div>
  );
}

export default List;
//Greet.tsx
import "./Greet.css"
import List from "./List"
const Greet = ()=> {
  return (
    <div className="component">
      <List title="買い物リスト" color="red" />
      <List />
    </div>
  );
}

export default Greet;

ポイントは2つです。

  • 渡さなくてもよいpropsなので、型に?を付けている
  • デフォルト値は分割代入の中でtitle = "アイテム一覧"と書いている

ulの上にh3を置くために全体をdivで囲んでいますが、ここは第六回で学んだフラグメント(<>)を使っても構いません。

チェックリスト

  • propsは属性名と属性値の形で渡している
  • 受け取る側でtypeを使って型を宣言している
  • 渡さない可能性があるpropsには型に?を付けている
  • props.xxxではなく分割代入で受け取れている
  • デフォルト値は分割代入の中で設定している
  • 分割代入はReactではなくTypeScriptの機能だと理解している
  • 別名で受け取りたいときはコロンを使うと知っている
  • propsという引数名は慣習にすぎないと分かっている
  • 表示を変えたいときはprops経由で渡す、という原則を意識している

第九回はここまで。
次回はpropsにいろいろな値を渡す方法について学習していきます!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?