React Props

React において、Props(プロパティ)は、データを親コンポーネントから子コンポーネントに渡すための仕組みです。Props は読み取り専用で、子コンポーネントはそれらを直接変更できません。親コンポーネントが管理・更新する必要があります。

state と props の主な違いは次のとおりです。propsprops は不変ですが、state はユーザーとのインタラクションに応じて変更できます。これが、一部のコンテナコンポーネントが state を定義してデータを更新・変更する必要がある理由です。一方、子コンポーネントは props を通じてのみデータをやり取りできます。


Props を使用する

Props を渡す構文:

<ComponentName propName={propValue} />

以下の例は、コンポーネント内で props を使用する方法を示しています。

React の例

function HelloMessage(props) { return <h1>Hello {props.name}!</h1>; } const element = <HelloMessage name="サンプル"/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element );

試してみる »

この例では、name 属性は props.name で取得されます。


デフォルト Props

コンポーネントクラスの defaultProps 属性を使って props にデフォルト値を設定できます。例は次のとおりです。

React の例

class HelloMessage extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } HelloMessage.defaultProps = { name: 'サンプル' }; const element = <HelloMessage/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element );

試してみる »

複数の Props

複数の属性を子コンポーネントに渡すことができます。

例

const UserCard = (props) => {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>Age: {props.age}</p>
      <p>Location: {props.location}</p>
    </div>
  );
};

const App = () => {
  return (
    <UserCard name="Alice" age={25} location="New York" />
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

propTypes の検証

propTypes は React が提供する、コンポーネントの props の型チェックを行うためのツールです。

prop-types ライブラリを使用して、コンポーネントの props の型チェックを行うことができます。

React では、propTypes はコンポーネントの静的プロパティとして定義します。まず、prop-types パッケージをインストールする必要があります:

npm install prop-types

次に、コンポーネントファイルに prop-types をインポートし、propTypes プロパティを定義します。以下に例を示します。

例

import PropTypes from 'prop-types';

const Greeting = (props) => {
  return <h1>Hello, {props.name}!</h1>;
};

Greeting.propTypes = {
  name: PropTypes.string.isRequired
};

const App = () => {
  return (
    <div>
      <Greeting name="Alice" />
      {/* <Greeting /> // このコード行は、name が必須のためコンソールに警告を表示します */}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

コールバック関数を Props として渡す

関数を props として子コンポーネントに渡すことができます。子コンポーネントはこれらの関数を呼び出して、親コンポーネントと通信できます。

例

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { message: '' };
  }

  handleMessage = (msg) => {
    this.setState({ message: msg });
  };

  render() {
    return (
      <div>
        <ChildComponent onMessage={this.handleMessage} />
        <p>Message from Child: {this.state.message}</p>
      </div>
    );
  }
}

const ChildComponent = (props) => {
  const sendMessage = () => {
    props.onMessage('Hello from Child!');
  };

  return (
    <div>
      <button onClick={sendMessage}>Send Message</button>
    </div>
  );
};

ReactDOM.render(<ParentComponent />, document.getElementById('root'));

Props の分割代入

関数コンポーネントでは、props を分割代入することでコードを簡素化できます。

例

const Greeting = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};

const App = () => {
  return <Greeting name="Alice" />;
};

ReactDOM.render(<App />, document.getElementById('root'));

まとめ

  • Props の受け渡しと使用:親コンポーネントは子コンポーネントにデータを渡し、子コンポーネントはpropsを通じて受け取ります。
  • デフォルト Props:defaultPropsを使用してコンポーネントのデフォルト属性値を設定します。
  • PropTypes の検証:prop-typesライブラリを使用して props の型チェックを行います。
  • コールバック関数の受け渡し:親コンポーネントは関数を props として子コンポーネントに渡すことができ、コンポーネント間の通信を実現できます。
  • Props の分割代入:関数コンポーネントで props を分割代入してコードを簡素化します。

State と Props

以下の例は、アプリケーションで state と props を組み合わせて使用する方法を示しています。親コンポーネントで state を設定し、子コンポーネントに props を使ってそれを渡すことができます。render 関数内で、name と site を設定して親コンポーネントから渡されたデータを取得します。

React の例

class WebSite extends React.Component { constructor() { super(); this.state = { name: "サンプル", site: "https://www.example.com" } } render() { return ( <div> <Name name={this.state.name} /> <Link site={this.state.site} /> </div> ); } } class Name extends React.Component { render() { return ( <h1>{this.props.name}</h1> ); } } class Link extends React.Component { render() { return ( <a href={this.props.site}> {this.props.site} </a> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <WebSite /> );

試してみる »

Props の検証

React.PropTypes は React v15.5 以降、prop-typesライブラリに移動されました。

<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prop-types/15.8.1/prop-types.min.js" type="application/javascript"></script>

Props の検証にはpropTypesを使用します。これにより、アプリケーションのコンポーネントが正しく使用されることを保証できます。React.PropTypes は、渡されたデータが有効かどうかを検証するための多くのバリデータを提供します。無効なデータが props に渡されると、JavaScript コンソールに警告が表示されます。

以下の例では、Mytitle コンポーネントを作成します。属性 title は必須で、文字列型です。文字列以外の型は自動的に文字列に変換されます:

React 16.4 の例

var title = "サンプル"; // var title = 123; class MyTitle extends React.Component { render() { return ( <h1>Hello, {this.props.title}</h1> ); } } MyTitle.propTypes = { title: PropTypes.string }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> );

試してみる »

React 15.4 の例

var title = "サンプル"; // var title = 123; var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } }); const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> );

試してみる »

もちろん、さらに多くのPropTypesバリデータとその使用方法を紹介できます。以下は、よく使われるPropTypesバリデータの説明です:

基本データ型

  • PropTypes.string:文字列
  • PropTypes.number:数値
  • PropTypes.boolean:ブール値
  • PropTypes.object:オブジェクト
  • PropTypes.array:配列
  • PropTypes.func:関数
  • PropTypes.symbol:Symbol

特殊な型

  • PropTypes.node:レンダリングできる任意の内容:数値、文字列、要素、または配列(これらの型を含む)
  • PropTypes.element:React 要素
  • PropTypes.instanceOf(Class):あるクラスのインスタンス

組み合わせ型

  • PropTypes.oneOf(['option1', 'option2']):列挙型。値は提供されたオプションのいずれかである必要があります
  • PropTypes.oneOfType([PropTypes.string, PropTypes.number]):複数の型のうちの1つ
  • PropTypes.arrayOf(PropTypes.number):ある型で構成される配列
  • PropTypes.objectOf(PropTypes.number):ある型で構成されるオブジェクト
  • PropTypes.shape({ key: PropTypes.string, value: PropTypes.number }):特定の形状を持つオブジェクト

その他

  • PropTypes.any:任意の型
  • PropTypes.exact({ key: PropTypes.string }):特定のキーを持つオブジェクトであり、余分なキーを他に持つことはできません

以下は、さまざまなPropTypesバリデータの使用方法を示すサンプルコードです:

例

import React from 'react';
import ReactDOM from 'react-dom/client';
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  static propTypes = {
    title: PropTypes.string.isRequired, // 文字列である必要があり、必須です
    age: PropTypes.number,              // 任意の数値
    isAdmin: PropTypes.bool,            // 任意のブール値
    user: PropTypes.shape({             // 特定の形状を持つオブジェクトである必要があります
      name: PropTypes.string,
      email: PropTypes.string
    }),
    items: PropTypes.arrayOf(PropTypes.string), // 文字列の配列である必要があります
    callback: PropTypes.func,           // 任意の関数
    children: PropTypes.node,           // 任意のレンダリング可能な内容
    options: PropTypes.oneOf(['option1', 'option2']), // 特定の値のいずれかである必要があります
  };

  render() {
    return (
      <div>
        <h1>{this.props.title}</h1>
        {this.props.age && <p>Age: {this.props.age}</p>}
        {this.props.isAdmin && <p>Admin</p>}
        {this.props.user && (
          <div>
            <p>Name: {this.props.user.name}</p>
            <p>Email: {this.props.user.email}</p>
          </div>
        )}
        {this.props.items && (
          <ul>
            {this.props.items.map((item, index) => (
              <li key={index}>{item}</li>
            ))}
          </ul>
        )}
        {this.props.callback && (
          <button onClick={this.props.callback}>Click me</button>
        )}
        {this.props.children}
        {this.props.options && <p>Option: {this.props.options}</p>}
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <MyComponent
    title="Hello, World!"
    age={30}
    isAdmin={true}
    user={{ name: "John Doe", email: "[email protected]" }}
    items={['Item 1', 'Item 2', 'Item 3']}
    callback={() => alert('Button clicked!')}
    options="option1"
  >
    <p>This is a child element</p>
  </MyComponent>
);
その他の拡張