LoginSignup
3
2

More than 3 years have passed since last update.

Reactの基礎勉強記録

Last updated at Posted at 2021-04-18

はじめに

初学者の私がReactについて学んだことをアウトプットする記事です。
主な目的は自分がこの記事を開けばReactについて復習できるようにする備忘録です。

目次

  • Reactとは
  • JSXの基礎知識と文法
  • create-react-app
  • コンポーネントの基本データの受け渡しと再利用
  • コンポーネントの状態stateの設定と取得と変更
  • コンポーネントのライフサイクル 副作用の有る処理を書こう
  • importとexport モジュールを使いこなそう
  • React-Hooks 関数コンポーネントでもステートを使おう
  • React-Hooks 関数コンポーネントでもライフサイクルを使おう

Reactとは

概要

Facebook社が開発したライブラリで、WebのUIを作るもので、決してSPAを作るものではない。
チャットボットだけReact、ボタン機能だけReactで実装することも出来る。

コンポーネントとは

UIは2つに分類される。
1. 見た目(View)
2. 機能(Controller)
コンポーネント=見た目+機能

コンポーネントのツリー構造

HTMLの下にヘッダーやメイン、その下にnav,login-button,content,linkなどが存在する。

DOM

DOM=Document Object Model=インターフェイス
HTMLにアクセスする窓口
HTML構造、見た目、コンテンツを変更する

Virtual DOMとは

ブラウザのレンダリングと別管理、効率よくDOM操作できる。

通常のDOM操作の場合、

document.getElementById('hoge').innerText = 'fuga'

ReactのVirtualDOM操作

render(<div id='hoge'>fuga</div>)

差分描画について

変更されたVirtualDOMの差分を再描画するので、従来のHTMLをまるごと受け渡しするより早く描画できる。

JSXが使える

JavaScript内でHTMLっぽく書ける。
Reactの最大の強み。

JSXの基礎知識と文法

JSXとは

JavaScript内でHTMLを簡単に記述するための言語で、JavaScriptの拡張言語である。
Facebook社が開発していて、Reactの公式ドキュメントはほぼJSXで書かれている。
Reactでは業界標準である。

なぜJSXなのか (わかりにくいので後で書き直します)

通常のJavaScriptでHTMLを記述すると(DOM操作)

const fuga = '<h1>Hello,World!</h1>'
document.getElementById('hoge').innerHTML = huga

となる。
量が増えると、const foo='<h2>React Commentary</h2>したあと、それのID、中身を変数で代入しなければならない。それをそれぞれやらなければならないので、わけわからなくなる。
JSXを使えばHTMLっぽく書けて可読性が高い。それだけでJSXを使う理由がある。

トランスパイラとは

翻訳のような役割。
JSXの構文はブラウザが理解出来ないので、トランスパイラで翻訳する必要がある。
例えば、JSXからJavaScript(ES6)など。
トランスパイラはBabel,CoffeeScript,TypeScriptなどが使われる。

もしJSXが無かったら

React.createElementを使う羽目になり、いちいちこれでHTMLを宣言しなければいけなくて面倒。
トランスパイラで翻訳されたあとはこのcreateElementが使われている。

基礎文法

Reactパッケージのインストールが必須。

.jsxファイルの先頭で宣言する。
import React from 'react'

HTMLとほぼ同じ記述

例外はある。
<div class='hoge'> → <div className='hoge'>
など。

{}内に変数や関数を埋め込める

const foo = <h1>Hello</h1>
{foo}

Helloが表示できる。
つまり、{}内だけはJavaScriptの空間に出来る。

変数名などは全てキャメルケースで書く

javascriptなので、fooBar,classNameなど、ラクダのコブのように単語の区切りが大文字になる。
ハイフンで繋ぐケバブケースは使わない。foo-bar,class-nameなどは禁止。

空要素は必ず閉じる。

HTMLでは<input ~~~ >でよいが、Reactでは<input ~~~ /> <img ~~~ />のように、/>で閉じる必要がある。

create-react-app

簡単に言うと

React開発環境をワン・コマンドで。

必要なもの

  • node 8.10
  • npm 5.6
  • インストール用にhomebrewとnodebrew

なぜこれを使うのか

普通に環境構築しようとすると、くっっっっっっっっそ難しい。
トランスパイラのbabelやバンドラのwebpackの設定が必要だからである。
熟練者でもこれは難しいらしい。

create-react-appで作成されるフォルダ

  • src:コンポーネントを作るjsファイルを入れる
  • public:htmlファイルや設定ファイルを入れる
  • build:本番環境用のファイルを入れる

src(ソースフォルダ)の中身

js,cssをrootに書き換えて、publicのindex.htmlで出力する。

publicフォルダの中身

  • favicon.ico:タブの左側のアイコン
  • 画像ファイル
  • manifest.json:ホーム画面に追加が出来る設定ファイル

buildフォルダの中身

srcの中に入ってたものを1つにまとめて入れてある。
まとめる役割を持つのがバンドラ(webpack)。

コマンド集

npm run build

srcとpublic内のファイルを1つにまとめて(バンドル)、buildディレクトリに出力する。
同時にトランスパイル(翻訳)もされている。

npm start

ローカルサーバーを起動してReactアプリを確認できる。

npm run eject

babelやwebpackの設定を変更する

その他の環境構築ツール

  • Next.js : SSR,SSGが出来る。SEO対策に最適。これからどんどん流行るであろう今最もアツいフレームワーク。
  • Gatsby : 静的ウェブサイトに使える。

コンポーネントの基本 データの受け渡しと再利用

最初に

コンポーネントとは見た目プラス機能ということ

なぜコンポーネントを使うのか

再利用するため

ボタンコンポーネントに引数を渡して(props)色んな場所で使う

分割統治するため

それぞれのコンポーネント同士は互いに関連しあわないことで管理しやすい(疎結合)

変更に強くするため

分割統治すると変更に強くなる。
コンポーネントを変更しても、他のコンポーネントには一切関係がない(アトミックデザイン)

コンポーネントの種類

  • Class Component : クラスによって定義されたコンポーネント(React-Hooksがデファクトスタンダードになっている現在、ほぼ使われていないので注意)
  • Functional Component : 関数型で定義されたコンポーネント

FunctionalComponentの特徴

  • ES6のアロー関数で記述
  • stateを持たない(stateless)
  • propsを引数に受け取る
  • JSXをreturnする。

ClassComponentの特徴

  • React.Componentを継承
  • ライフサイクルやstateを持つ
    コンポーネントが出てくるときにどう動くか、消えるときにどう動くか、これをライフサイクルと言う。
  • propsにはthisが必要
    this.propsの意味は、このクラス内のporpsだよって意味
  • renderメソッド内でJSXをreturnする
  • 記述量が多い代わりに状態(state)を持てる
    (最近はクラスコンポーネントを使わず、なるべくファンクショナルコンポーネントを使う。)

propsでデータを受け渡す

親コンポーネント

const Blog = () => {
  return (
    <div>
      <Article title={'React'} />
    </div>
   );
}

子コンポーネント

const Article = (props) => {
  return (
    <div>
      <h2>{props.title}</h2>
    </div>
  );
}

受け渡せるデータ型

{}内に記述する。
文字列、数値、真偽値、配列、オブジェクト、変数、何でも渡せる。
文字列は{}無しでもOK

再利用する

コンポーネントを使い回す。

<Articl title={'React'} />
<Articl title={'JSX'} />

コンポーネントの状態 stateの設定と取得と変更

状態(state)とは

  • コンポーネント内で管理する変数
  • ローカルステートと呼ばれる。(reduxではグローバルステートがある。)
  • propsとして子コンポーネントに渡せる。

なぜstateを使うのか

  • render()内で値を変更してはいけないから。 (stateが変わると再レンダーされる。その際にまたstateが変わって再レンダーされる。以下無限ループ)
  • setState()で値を変更する。
  • stateの変更=再レンダーのきっかけ ページリロードせず表示を切り替えられる。

stateの設定方法

  • ClassComponentが前提
  • constructor()内で宣言
  • オブジェクト型で記述
constructor(props) {
    super(props);
    this.state = {
        isPublished: false }}

stateの取得

  • 同コンポーネント内ならthis.state.key名で取得できる
  • 子コンポーネントで参照したい場合はpropsで渡す
  • <Article title='React' isPublished={this.state.isPublished} />で渡せる

stateの変更方法

  • setState()を使う
  • 関数にラップするのが一般的
  • setState()内に記述されたstateのみを変更
  • 公開状態を反転させる関数を定義する
togglePublished = () => {
    this.setState({
        isPublished: !this.state.isPublished }) };
// ここの!は反転させるの意味

コンポーネントのライフサイクル 副作用のある処理を書こう

ライフサイクルとは

  • コンポーネントの時間の流れ
  • 生まれて、成長して、死ぬまでの循環
  • それぞれの段階で必要な処理を記述
  • Reactの基礎中の基礎

3種類のライフサイクル

  • Mounting : コンポーネントが配置される(生まれる)期間
  • Updating : コンポーネントが変更される(成長する)期間
  • Unmounting : コンポーネントが破棄される(死ぬ)期間

なぜライフサイクルを使うのか

  • 関数の外に影響を与える関数を記述するため DOM変更、API通信、ログ出力、setState()など
  • 副作用=適切な場所に配置すべき処理

それぞれの期間

  • Mounting→constructor()→render()→componentDidMount()
  • Updating→render()→componentDidUpdate()
  • Unmounting→componentWillUnmount()

主要メソッド(Mount)

  • constructor() : 初期化(stateなど)
  • render() : VDOMを描画(JSXをリターン)
  • componentDidMount() : render()後に1度だけ呼ばれる。リスナーの設定やAPI通信に使われる

主要メソッド(Update)

  • render() : VDOMを再描画
  • componentDidUpdate() : 再render()後に呼ばれるスクロールイベントや条件付きイベント 例(新しいコメントが入ってきたときに、そこにスクロールするなど。)

主要メソッド(Unmount)

  • componentWillUnmount() : コンポーネントが破棄される直前にリソースを開放するため リスナーの解除など。API通信の解除など。

importとexport モジュールを使いこなす

モジュール化とは

  • 多言語では昔からある概念
  • JavaScriptではES6から
  • 基本的に1ファイル1モジュール
  • 任意の場所で読み込める

モジュール化の威力

  • 分割統治できる : 大規模プログラムでも管理しやすい
  • 任意の場所で読み込める : 必要なものを必要な分だけ
  • 再利用ができる : 何度も同じコードを書かなくてよい
  • Reactはモジュール化を強く推奨してる

名前付きexport

  • 1モジュールから複数の関数をexport
  • クラスはexportできない
  • export funcrion 関数名(){}
  • export const 関数名 = () => {}

名前無し(default)export

  • 1ファイル(1モジュール)1export
  • ES6で推奨方法
  • アロー関数は宣言後にexport
  • クラスをexportできる

モジュール全体のimport

  • 名前無し(default)exportしたモジュールをimportする
  • モジュール全体のimport

関数ごとのimport

  • 名前付きexportされたモジュールをimportする
  • {}内にimportしたい関数名

別名import

  • 別名(エイリアス)をつけてimportできる
  • モジュール全体なら* as name
  • モジュール一部なら{A as B}

ReactHooks 関数コンポーネントでもステートを使おう

フックとは

  • クラスの機能を関数コンポーネントでも使える
  • React16.8から導入
  • 100%後方互換だから小さく導入できる

なぜフックを使うのか

  • シンプルさを保つため
  • クラスコンポーネントは難しい
  • thisという悪魔 : JavaScriptでは他の言語のthisとは違う挙動をする
  • stateを扱うロジックが複雑
  • 複数のライフサイクルメソッドに副作用のある処理がまたがる : componentDidMountでイベントリスナーを設定して、componentDidUnmountで解除する。この記述をまとめたい。
  • これらを解決するのがフック

useState()を使おう

  • ステートフックと呼ばれる
  • クラスコンポーネントでいうthis.statethis.setState()を代替する
  • 複数のstateを扱うときはstateごとに宣言

useState()の使い方

1. useState関数をインポート : import React,{useState} from 'react;
2. 宣言する : const [isPublished, togglePublished] = useState(false);
左から順に「state変数名」、「state変更関数名」、「state初期値」
3. JSX内で使う : <input ~~~ onClick={() => togglePublishec(!isPublished)} />

ReactHooks 関数コンポーネントでもライフサイクルを使う

useEffect()のメリット

  • ライフサイクルメソッドを代替出来る
  • 関数コンポーネントでライフサイクルを使える
  • コードをまとめられる
  • 機能ベースがよい(何をやっているのかわかる)
  • 時の流れベースはよくない(ライフサイクルのメソッドごとがわかりづらい)

useEffect()の仕組み

  • レンダー毎にuseEffect()内の処理が走る
  • 代替出来るメソッドは以下
  • componentDidMount
  • componentDidUpdate
  • componentDidUnmount

パターン1 レンダーごと

  • 基本の形
  • useEffect()内にCallback関数を書く
  • Callbackはレンダー毎に呼ばれる
  • returnするCallback関数はアンマウント時に呼ばれる(クリーンアップ関数)
useEffect(() => {
    console.log('Render!')
    return () => {
        console.log('Unmounting!')}})

パターン2 マウント時のみ

  • 第2引数の配列内の値を前回レンダーと今回レンダーで比較 : 変更があればCallback関数を実行
  • 第2引数に空の配列を渡すと最初の1回のみ実行される
useEffect(() => {
    console.log('Render!')}, [] )

パターン3 マウントとアンマウントのみ

  • 1と2の複合系
  • 通常のCallbackはマウント時のみ
  • アンマウント時はreturn内のクリーンアップ関数が実行
useEffect(() => {
    console.log('Render!')
    return () => {
        console.log('Unmounting!)} }, [] )

パターン4 特定のレンダー時

  • マウント時に実行される
  • limitの値が変わったときに実行される
  • 例えば、limitの値がtrueからfalseになったとき。
const [limit, release] = useState(true);
useEffect(() => {
    console.log('Render!') }, [limit])
3
2
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
3
2