search
LoginSignup
3

More than 1 year has passed since last update.

posted at

updated at

Organization

Reactアプリケーション開発入門

■create-react-appのインストール&Hello Worldの表示

create-react-appはFacebookが提供しているCLIツールです。
環境構築の手間をスキップして学習に集中できます。

// create-react-appのインストール
yarn global add create-react-app

// Reactアプリケーションの作成
create-react-app hello-world

// hello-worldに移動
cd hello-world

// 開発開始
yarn start

7b695480-013f-11eb-82ee-a6989fc53549.png

ファイル構造はこんなかんじです。
7b695480-013f-11eb-9223-07d42cd3a344.png

Hello Worldを表示するにはsrc/App.js内をこのように書き換えます。

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code>and save to reload {/* この行をHello Worldに書き換える */}
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

これでHello Worldが表示されました。
7c01eb00-013f-11eb-8f31-3b24ac4893e5.png

ちなみにこのreturn()内の部分はぱっと見HTMLに見えますが、実際はJSXというものになっています。
詳細は公式をご確認ください。( https://ja.reactjs.org/docs/introducing-jsx.html )

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  //このreturnの中がJSX
  return ( 
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello World
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

■コンポーネントについて

Reactのコンポーネントには「関数コンポーネント」と「クラスコンポーネント」の二種類があります。

<関数コンポーネント>

実は先ほどのHello Worldを表示した時のApp.jsが既に関数コンポーネントの形になっていました。

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello World
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

わかりやすく余計な部分を省いた形が下記になります。
※ちなみにですが、JSXが内部的にReactを使用しているため「import React from 'react';」の記述を無くすとエラーになります。

import React from 'react';

function FunctionComponentA() {
  return (
    <div className="function-component_A">
      function-component_Aです
    </div>
  );
}

export default FunctionComponentA;

このようにsrc/index.jsに追加することで反映されます。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import FunctionComponentA from './FunctionComponentA' //ここに追加
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <FunctionComponentA /> {/* ここに追加 */}
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

7c9a8180-013f-11eb-8449-abdbaf2c3e57.png

このようにアロー関数の形で定義することもできます。

import React from 'react';

const FunctionComponentB = () => {
  return (
    <div className="function-component_B">
      function-component_Bです
    </div>
  );
}

export default FunctionComponentB;

<クラスコンポーネント>

クラスコンポーネントはこのように定義します。

import React, { Component } from 'react';

class ClassComponent extends Component {
  render() {
    return (
      <div className="class-component">
        ClassComponentです
      </div>
    )
  }
}

export default ClassComponent;

Componentを継承したクラスとして定義します。

<関数コンポーネントとクラスコンポーネントそれぞれの特徴>

関数コンポーネント
・簡潔に書けるので基本はこちらが望ましい。
・状態管理によるレンダー制御ができない。

クラスコンポーネント
・状態管理によるレンダー制御が可能。
・ローカルstateやライフサイクルメソッドが利用可能。

■props

こちらが見本になります。

import React from 'react';

const Parent = () => {
  return (
    <div>
      <strong>表示されるとこうなります</strong>
      <Child name={"ポール・マッカートニー"} instrument={"ベース"} />
      <Child name={"ジョン・レノン"} instrument={"ギター"} />
      <Child name={"ジョージ・ハリスン"} instrument={"ギター"} />
      <Child name={"リンゴ・スター"} instrument={"ドラム"} />
    </div>
  )
}

const Child = (props) => {
  return (
    <div>僕は{props.name}です担当は{props.instrument}です</div>
  )
}

export default Parent;

7dcbae80-013f-11eb-8c85-0e24cc520e73.png

Child(子コポーネント)をParent(親コンポーネント)で利用する際に属性のような形でpropsを渡すことができます。
渡ったpropsはChild側で受け取り、利用するという流れになります。

データを配列で一括に渡したいと言う時には、「map」を利用することで実現可能です。
下記キャプチャでは、配列ビートルズをmapで展開しています。

import React from 'react';

const Parent2 = () => {
  const beatles = [
    {
      name: "ポール・マッカートニー",
      instrument: "ベース"
    },
    {
      name: "ジョン・レノン",
      instrument: "ギター"
    },
    {
      name: "ジョージ・ハリスン",
      instrument: "ギター"
    },
    {
      name: "リンゴ・スター",
      instrument: "ドラム"
    }
  ]
  return (
    <div>
      <strong>表示されるとこうなります(map)</strong>
      {
        beatles.map((beatlesMember, index) => {
          return <Child name={beatlesMember.name} instrument={beatlesMember.instrument} key={index} />
        })
      }
    </div>
  )
}

const Child = (props) => {
  return (
    <div>僕は{props.name}です担当は{props.instrument}です</div>
  )
}

export default Parent2;

■prop-types(型チェック)

こちらが見本になります。

import React from 'react';
import PropTypes from 'prop-types' //これをimportします。

const Parent = () => {
  return (
    <div>
      <strong>表示されるとこうなります</strong>
      <Child name={"ポール・マッカートニー"} year={1942} guitar={true} />
      <Child name={"ジョン・レノン"} year={1940} guitar={true} />
      <Child name={"ジョージ・ハリスン"} year={1943} guitar={true} />
      <Child name={"リンゴ・スター"} year={1940} guitar={false} />
    </div>
  )
}

const Child = (props) => {
  return (
  <div>僕は{props.name}です{props.year}年生まれです{props.guitar ? 'ギターを弾けます。' : 'ギターは弾けません。'}</div>
  )
}

//ここでpropsに対しての型定義を行っています。
Child.propTypes = {
  name: PropTypes.string,
  year: PropTypes.number,
  guitar: PropTypes.bool
}

export default Parent;

prop-typesを導入する手順としては、
1. PropTypesをimportする。
2. コンポーネントのpropsに対して型定義を行う。
になります。

●動作確認
「name="リンゴ・スター"」の部分のyearとguitarの値を文字列に変えてみます。

import React from 'react';
import PropTypes from 'prop-types' //これをimportします。

const Parent = () => {
  return (
    <div>
      <strong>表示されるとこうなります</strong>
      <Child name={"ポール・マッカートニー"} year={1942} guitar={true} />
      <Child name={"ジョン・レノン"} year={1940} guitar={true} />
      <Child name={"ジョージ・ハリスン"} year={1943} guitar={true} />
      <Child name={"リンゴ・スター"} year={"1940"} guitar={"false"} /> {/* ここの値を間違ったもの(文字列)に変更 */}
    </div>
  )
}

const Child = (props) => {
  return (
  <div>僕は{props.name}です{props.year}年生まれです{props.guitar ? 'ギターを弾けます。' : 'ギターは弾けません。'}</div>
  )
}

//ここでpropsに対しての型定義を行っています。
Child.propTypes = {
  name: PropTypes.string,
  year: PropTypes.number,
  guitar: PropTypes.bool
}

export default Parent;

7efcdb80-013f-11eb-8bb6-08f6fd378bcd.png

無事にエラーが吐き出されました。

■state

こちらが見本になります。
countというstateを持ったCounterコンポーネントを作成しました。

import React, { Component } from 'react';

class Counter extends Component {
  // 状態を持たせるための処理
  constructor(props) { // コンポーネントの初期化時に呼び出される
    super(props)
    // this.stateでstateにアクセスできる。
    this.state = { count: 0 }
  }

  countUp = () => {
    this.setState({ count: this.state.count + 1 }) // stateを変更する時は必ずsetState()を使用する。
  }

  countDown = () => {
    this.setState({ count: this.state.count - 1 }) // stateを変更する時は必ずsetState()を使用する。
  }

  render() {
    return (
      <div className="counter">
        <div>count:{ this.state.count }</div>
        <button onClick={this.countUp}>+1</button>
        <button onClick={this.countDown}>-1</button>
      </div>
    )
  }
}

export default Counter;

7f957200-013f-11eb-9bd5-315fd9447874.png

以下、ポイントになります。

・レンダー制御が必要なのでクラスコンポーネントで作成した。
・stateの値を変更する時はsetState()を必ず使用する。
・this.stateでstateにアクセスする。

:christmas_tree: FORK Advent Calendar 2020
:arrow_left: 16日目 Full Static Generationを試す @AsaToBan
:arrow_right: 18日目 Reactで神経衰弱を作ってみた @ktn

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
What you can do with signing up
3