React Bootcampのリポジトリ

Overview

ReactBootcamp 第一回勉強会後の開発ドキュメント

前回まで

次回までの目標

  • React の環境を構築し、React の使い方を掴む

今週のやることリスト

  • PC に React の開発環境を構築する
  • エディタをインストール(VS code 推奨)
  • React プロジェクトの作成
  • React を起動してみる
  • React のソースコードを書いてみる

次回までの目標

  • React のデザインシステムを理解し、アプリの見た目を整えよう!

今週のやることリスト

  • React のコンポーネントの概念を理解する
  • React の State とライフサイクルについて理解する
  • React のデザインスシテムについて理解する
  • Youtube アプリの構築に必要なコンポーネントの設計
  • 必要ライブラリーのインストール
  • デザインの前に、ルーティングを作成
  • Header のデザインを作成
  • Sidebar のデザイン作成
  • ビデオカードのデザイン作成
  • 動画再生画面のデザイン作成
  • 動画アップロード画面のデザイン作成

ReactBootcamp 第二回目勉強会ドキュメント

第二回目は、React 特有の概念や機能を理解しながら、実際のアプリケーションで使用する画面デザインを React でデザインしていきます。

わからないこと、疑問点、ドキュメントやソースコードの間違いなどは下記 Discord にてメッセージお願いします。

React Bootcamp Discord

React のコンポーネントの概念を理解する

  • コンポーネントとは

    コンポーネントにより UI を独立した再利用できる部品に分割し、部品それぞれを分離して考えることができるようになります。  概念的には、コンポーネントは JavaScript の関数と似ています。(“props” と呼ばれる)任意の入力を受け取り、画面上に表示すべきものを記述する React 要素を返します。

    コンポーネントと props - React Docs

コンポーネントとは、React でアプリを構築するために最初に出てくる概念です。

皆さんも実はすでにこのコンポーネントを記述し、実際に画面に表示しています。(第一回目勉強会参照

第一回目勉強会でindex.tsxApp.tsxというファイルを編集しました。

このうち、App.tsx がいわゆるコンポーネント(Component)と呼ばれるものです。

  • Why コンポーネント?

ではなぜ React ではこのコンポーネントという概念が存在するのでしょうか?

それは、ソースコードの再利用性と凝集度※を高め、開発がしやすくメンテナンス性の高いコードを書くためです。

※ひとつの役割のためだけに存在しているコンポーネントは凝集度が高い。
反対にいくつもの役割をこなしているコンポーネントは凝集度が低い。

例として、今回の React Bootcamp で作成する Youtube アプリのデザインを見ていきましょう。

Youtube Mock

このデザインでは、このような形で大きなコンポーネントグループに分けることができます。

Youtube Component Group

それぞれ、「Layout」「Header」「Sidebar」「Main」という大きなコンポーネントの塊にグルーピンを行いました。

このグルーピングで以下の 4 つのコンポーネントが生まれました

Layout:「Header」「Sidebar」「Main」をまとめ上げ、上記のようなデザインを表示するコンポーネント
Header:ロゴや検索バーなどを表示するコンポーネント
Sidebar:ナビゲーションバーなどを表示するコンポーネント
Main:アプリケーションのメインとなるデザインを表示するコンポーネント

それぞれ、そのコンポーネントがどのような役割を持っているかが明確に伝わってきますね。

ここで、重要なのは、Headerコンポーネントは Header が存在するデザインであれば、全てのページで同じHeaderコンポーネントを流用できます。

例えば、下記のようなデザインの場合、

Youtube Component sidebar

Sidebar はなくなりましたが、Headerは全く同じデザインですよね?

Headerコンポーネントは、Sidebarコンポーネントがあるかどうか、Mainコンポーネントのデザインがどうであるか、を全く気にすることなくどこでも同じHeaderコンポーネントとして使用することができます。

このコンポーネントとして役割を「閉じ込めて」自身のコンポーネントのことだけを気にしていればいいという設計が React 最大の特徴であり、シンプルさを実現しています。

このような形で、React ではコンポーネントと呼ばれるパーツをたくさん繋ぎ合わせていくことで一つの巨大なアプリケーションが構築できるように設計されています。

  • コンポーネントの実態

では、そんなコンポーネントはどのようにしてソースコードの中に出てくるのでしょうか?

実は冒頭で説明した通り、皆さんは既にコンポーネントを作成しています。

第一回目勉強会でのソースコードを見てましょう。

logo

ReactBootcamp Youtube App

第一回目勉強会
); } export default App; ">
// src/App.tsx

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>
          ReactBootcamp Youtube App
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
         第一回目勉強会
        </a>
      </header>
    </div>
  );
}

export default App;

App.tsx内で作成したfunction App()という関数が、コンポーネントの実態です。

コンポーネントを作成するためには、function内でHTML要素returnすることで、コンポーネントとして使用できるようになります。

このときHTML要素は、JavaScript 内でHTML要素をいい感じに取り扱えるようにするJSXという名前で呼ばれています。

そして、この JSX を取り扱うためにファイルを.jsxとしています。

今回は、Typescript を使用してアプリケーションを構築していくので、.jsxではなく.tsxというファイル名になっていますが、違いは JavaScript か、Typescript か、の違いだけです。

誤解を恐れずに言えば、このjsx(tsx)で書かれたfunctionは全てコンポーネントであると言えます。

もう少し厳密に言うと、HTML要素を返すfunctionです。
HTML要素を返さないfunctionはただの関数であり、.jsx(.tsx)内に書かれていてもコンポーネントではありません。

何がコンポーネントであって、何がコンポーネントでないか、はコードを書きながら覚えていけると思います。

まずは、HTML要素を return しているfunctionは、コンポーネントとして覚えてもらって構いません。

React の state とライフサイクルについて理解する

では、実際にコンポーネントを書いていこう、という前にもう一つ大事な概念をお話ししなければなりません。

それはステート(state)と呼ばれる概念です。

  • state とは?

state とは、一言で言ってしまえば変数です。

プログラムを書く際に、必ず皆さんが宣言するあの変数と全く同じ概念です。

しかし、React のstateはかなり特徴的な書き方をします。

  • state の実態

stateの宣言の仕方は下記の通りです。

// reactのライブラリから、useStateをimport
import { useState } from 'react';

// 初期値を0としたstateを宣言
// const state = 0 のイメージ
const [state, setState] = useState(0);

// 値を変更する場合
// state の値を 1 に変更
setState(1)

すごい特徴的で、初めて見る人にはめんどくさい変数宣言をするなと感じたかもしれません。

値を格納する変数と、その値を変更する関数の二つに分かれています。

なぜこんな冗長な書き方をするのかを次の章で解説します。

import { useState } from 'react'とは?

これは、JavaScript(TypeScript)にてモジュールを使用する際に用いる構文です。

ES6 と呼ばれる JavaScript のバージョンで決められたモジュール読み込みの仕様です。

ES6 の他にもいろいろなバージョンがあります。
JavaScript のバージョン

JavaScript では他のファイルで作成したプログラムをモジュールという名前で読み込み使用できる仕組みがあります

例えば、import { useState } from 'react'reactモジュールからuseState関数をimportしています。

importしたら、そのファイル内ではuseStateを使用することができます。

他のファイルから関数やオブジェクトをimportしたい場合は、呼び出されるモジュールからexportを行わなければなりません。

// src/modules/module.ts
const ten = 10;

export const addTen = (value: number) => {
  return ten + value;
};
// src/modules/call.ts
import { addTen } from "./module";

// 10 + 10 = 20
const twenty = addTen(10);

call.tsからはmodule.tsで保存されているaddTenをインポートすることができます。

反対に、const tenexportされていないので、importすることができません。

また、importの方法は、はもう一つあります。

// src/modules/module.ts
const hundred = 100;

const addHundred = (value: number) => {
  return hundred + value;
};

export default addHundred;
// src/modules/call.ts
import myModuleFunction from "./module";

//  100 + 100 = 200
const twoHundred = myModuleFunction(100);

さっきとの違いは、export defaultでモジュールをexportしていることです。

export defaultexportしたオブジェクトは、呼び出し側(call.ts)で自由に名前をつけてimportすることができます。

どちらかを使うかは、明確なルールはありませんが、export defaultは 1 ファイルで 1 個しかオブジェクトをexportすることができません。

以下のような書き方はできません。

export default Function1
export default Function2 //Error!!

ReactBootcamp ではexport構文のみでのエクスポートを徹底し、export defaultは特別な理由がない限り使わないようにします。

理由としては、export defaultではどのようなオブジェクトが返されるかがインポート側で明示されおらずバグの元となります。

また、export defaultでは、インポート側で名前を自由につけれるため、誤ってオブジェクトの意図しない名前をつけてしまったがために、間違った使い方をしてしまう可能性があります。

このような理由から、React Bootcamp ではexportを積極的に使っていきます。

JavaScript特有の変数代入 const [state, setState] = useState(0)とは?

変数を[]で囲んで宣言していますね。

useStateは React 特有の関数ですが、const [state, setState]は JavaScript 特有の変数宣言です。

これは分割代入と呼ばれるものです。

分割代入とは、配列もしくはオブジェクトから個別の変数を取り出し、別個の変数に代入することを可能にする JavaScript の式です。

// one = 1
// two = 2
// three = 3
const num = [1, 2, 3]
const [one, two, three] = num


// オブジェクトの分割代入の場合は、プロパティ名と同じ変数名にする必要があります。
// ten = 10
// twenty = 20,
// thirty = 30
const { ten, twenty, thirty } = {
  one: 10,
  twenty: 20,
  thirty: 30
}

例えば、今回 const [state, setState] = useState(0)としている箇所では、以下のような処理が行われています。

// reactのどっかのファイルで
export function useState () {
  /**
   *
   * なんかの処理
   *
   *
   */

  return [state, setState]
}

※実際のソースコードをかなり簡略しているので、react のコードベースではもっと違った書き方をされています。

この時のreturn値が、[]で返されていますね。

useStatereturn [state, setState]を行なっているおかげで、useStateを使う際に分割代入で値を受け取ることができます。

これで、複数の値やオブジェクトを返したい時などに簡単にreturnを行うことができます。

  • Why state? ~ React のライフサイクル ~

なぜ React ではこのような冗長な変数宣言をしているのでしょうか?

それは、React が「state の値が変更されているかどうか」を判断して、画面表示を切り替えているからです。

そして、このsetStateと言う関数が「state の値が変更されているかどうか」と言う処理を呼び出しています。

React では、render()と言う処理を内部的に呼ぶ出すことで画面の更新を行なっています。
究極的には、この render()を呼び出せば画面の表示を強制的に更新することも可能、とも言えます(あまりそう言うことはしませんが。)

具体的に、どのような時に画面表示が切り替わり、そして切り替わらないのかを見ていきましょう。

ぜひ、実際にソースコードを書き直しながら画面を見てみてください。

{/* JSX内で変数を画面表示したい場合は、{}で変数を囲む必要があります。 */}

{state.toLocaleTimeString()}

); } export default App; ">
// src/App.tsx

import "./App.css";
import { useState } from "react";

function App() {
  // new Date()は現在時刻を取得します。
  const [state, setState] = useState(new Date());

  return (
    <div className="App">
      <header className="App-header">
        {/*
          JSX内で変数を画面表示したい場合は、{}で変数を囲む必要があります。
        */}
        <p>{state.toLocaleTimeString()}</p>
      </header>
    </div>
  );
}

export default App;

上記コードに書き直し、npm startで react を起動してみましょう。

React Clock Now

画面を表示した時の時間が表示されました。

では、この真ん中の時計を動かしてみましょう。

{ setState(new Date()); }, 1000); return (

{state.toLocaleTimeString()}

); } export default App; ">
import "./App.css";
import { useState } from "react";

function App() {
  const [state, setState] = useState(new Date());

  // setIntervalは、第二引数に指定した数値(単位はミリ秒)ごとに中の関数を実行します。
  // 1秒(1000ミリ秒)ごとにseState(new Date())を実行する関数
  setInterval(() => {
    setState(new Date());
  }, 1000);

  return (
    <div className="App">
      <header className="App-header">
        <p>{state.toLocaleTimeString()}</p>
      </header>
    </div>
  );
}

export default App;

もう一度画面表示をしてみましょう。

爆速で時計が完成しました。

React Clock

上記コードでは、1 秒ごとにsetStatestateの値を現在時刻で更新することで、画面表示が時計のように現在時刻を表示してくれます。

では反対に、下記のようなコードを書き直してみてください。

{ state = new Date(); }, 1000); return (

{state.toLocaleTimeString()}

); } export default App; ">
import "./App.css";

function App() {
  let state = new Date();

  setInterval(() => {
    state = new Date();
  }, 1000);

  return (
    <div className="App">
      <header className="App-header">
        <p>{state.toLocaleTimeString()}</p>
      </header>
    </div>
  );
}

export default App;

画面表示をしてみると行なっている処理は同じなのに、画面表示が更新されないことがわかります。

このように、React ではuseStateを用いたstate宣言とsetStateによる更新を行わなければ画面表示の変更すらできません。

これは、React を使う上で”一番大事”な概念なのでしっかり覚えてください。

constletとは?

先程のソースコードで、constを使った変数宣言と、letを使った変数宣言が出てきました。

この二つには明確な違いがあります。

const : 変数に値を再代入できません

let : 変数に値の再代入ができます。

const name = "マッケイ"
// エラー!!!
name = "React"

let fruit = "りんご"
// OK!!
fruit = "もも"

思わぬ変数の値の変更が起きぬように、開発では積極的にconstによる変数宣言を使っていきます。

React のデザインスシテムについて理解する

「React でデザインをしたいのですがどうすればいいですか??」

では、React で画面表示をしていく方法に入っていきたいと思います。

今まで、React ではJSXで書かれたコンポーネントで画面の表示をしていく方法を見てきました。

その際に、JSXの実態はただのHTMLでした。

では、このJSXで書かれたHTMLのデザインを整えるためには何が必要でしょうか?

そうです。HTMLのデザインを整えると言えばCSSです。

React のアプリケーションの「ビュー」の実態は、HTMLCSSただそれだけです。

なんと言うことでしょう。

HTMLCSSが書けてしまえば React アプリケーションのビューは書けてしまうのです。

つまり、React で「デザインをしたいのですがどうすればいいですか??」という質問の答えは簡単です。

「CSS を書け!」

  • React でデザインを行うために必要なもの

とはいえ、React でCSSを書くと言っても、様々な方法があります。

  • CSS を使った昔ながらの方法
  • CSS モジュールを使った方法
  • CSS フレームワークを使った方法
  • React 専用の UI フレームワークを使った方法
  • CSS in JS を使った方法

一つずつ、見ていきましょう。

※今回使う方法と How to だけ知りたいという方はこちらまでスキップしてください。

  • CSS を使った昔ながらの方法

こちらは、昔ながらのフロントエンドで用いられているグローバルな CSS ファイルに CSS を書いていく方法です。

React 以前のフロントエンド開発をしたことがある方は、この方法が一番馴染み深いと思います。

しかし、この方法は React ではもう使用しません。

理由は色々あるのですが、最も大きな理由は「コンポーネント指向の React との相性が最悪」ということです。

React は、コンポーネントという「箱」にコンポーネントに関係するものを閉じ込めることができるのに、グローバルな CSS ファイルで CSS を管理してしまうと、そのコンポーネントがどの CSS スタリングを使用しているのかの管理が煩雑になります。

なので、もし、React で CSS ファイルによるデザインを行いたい場合は次のCSSモジュールによってスタイルするのがスタンダードになっています。

ちなみに、create-react-appで作成したテンプレートプロジェクトはこのグローバルな CSS が用いられています。

  • CSS モジュールを使った方法

React で CSS ファイルを用いたスタイリングを行うときは、もうほとんどこの方法を使用します。

先程のグローバルな CSS スタリングと何が違うのか実際の画面を見てもらおうと思います。

{/* .App-headerではErrorが出るので、App.cssファイルの.App-headerを.AppHeaderに変更 */}

React Bootcamp

); } export default App; ">
import styles from "./App.module.css";

function App() {
  return (
    <div className={styles.App}>
      {/*
        .App-headerではErrorが出るので、App.cssファイルの.App-headerを.AppHeaderに変更
      */}
      <header className={styles.AppHeader}>
        <p>React Bootcamp</p>
      </header>
    </div>
  );
}

export default App;

まずは、1 行目からApp.cssからApp.module.cssに変更されています。

CSS モジュールを使用するのに、特別な設定は何も必要ありません。

ただ、CSS のファイル名をXXX.module.cssにするだけです。

そして、import 側からそのmodule.cssimport fromします。

今回の場合、stylesにはApp.module.cssの css ファイルで書かれている CSS のオブジェクトが格納されています。

イメージとしては以下のような感じです。

/**
 * [key: string]は任意の文字列
 * 実際のオブジェクトとしては、
 * {
 *  App: "任意のcss文字列"
 *  AppHeader: "任意のcss文字列"
 * }
 */
type styles = {
  [key: string]: string;
};

そして、CSS のclassを使いたい場所のHTML要素classNamestylesに格納されている CSS を指定しています。

これで、例えば

要素には、App.module.css内の.AppHeaderが指定されます。

とても簡単に CSS をいい感じにコンポーネントに閉じ込めることができるようになります。

他にも様々なメリットがありますが、それはまた後ほどご説明します。

  • CSS フレームワークを使った方法

CSS フレームワークとは、あらかじめ様々なスタリングが用意されている CSS ファイルをインポートすることで、最小限のスタイリングでデザインを完成させることができるツールです。

有名なフレームワークで言うと、BootstrapTailwindがあります。

CSS フレームワークには、何百個と言うスタリング済み CSS が用意されており、その CSS を HTML 要素に指定するだけで、デザインが完成します。

例えば、人数が少ない開発チームや、デザイナーがいない開発チームでは、このような CSS フレームワークを使用することで、開発スピードを大幅に上げることができます。

有名な CSS フレームワーク

Tailwind : https://tailwindcss.com/

Bootstrap : https://getbootstrap.com/

Foundation : https://get.foundation/

Semantic UI : https://semantic-ui.com/

最近では、React 界隈で Tailwind をデザインシステムに採用する動きがあります。

Tailwind には様々な CSS プロパティをclassベースで用意されており、それを組み合わせることで、あたかも HTML のマークアップ上で擬似的に CSS を記述してスタリングしているかのような開発体験を実現しています。

コミュニティも非常に活発に活動しており、これからのフロントエンドのトレンドとしては目が離せないフレームワークです。

  • React 専用の UI フレームワークを使った方法

次は、React UI フレームワークを使ったデザインの方法です。

こちらは、先程の CSS フレームワークを用いたスタリングと非常に似ており、既にデザイン済みのスタイリングを用いてデザインを実装することができます。

しかし、UI フレームワークは CSS フレームワークとは異なり、React で運用することを念頭に置いたフレームワークになっています。

よって、UI フレームワークを用いれば、CSS フレームワークよりもさらに簡単にデザインを実装することができます。

有名なフレームワークでは以下のようなものがあります。

Material-UI : https://material-ui.com/

Chakra UI : https://chakra-ui.com/

React Bootstrap : https://react-bootstrap.github.io/

Ant Design : https://ant.design/

この中では、Material-UI一強みたいなところがあり、Github スター数も70kと他を圧倒しています。

それもそのはず、Material-UI は Google が提唱している[マテリアルデザイン](https://material.io/design)に準拠したデザインシステムを取り入れています。

よって、Material-UIを用いた React 開発を行うと、どっかで見たことあるよなデザインを爆速で開発することができます。

いい感じのデザインでスピーディに開発したい場合は、Material-UIがおすすめです。

  • CSS in JS を使った方法

最後はスタリング界の異端児、CSS in JS を使った方法です。

まず、CSS in JS が何かと言うと、CSS のスタリングを JS のファイル内に記述するスタリング手法です。

説明するより見た方が早いと思うので、下記の例を見てください。

ログイン ; } ">
import styled from "styled-components";

// CSSによるスタイリング
const StyledButton = styled.button`
  background-color: black;
  font-size: 32px;
  color: white;
`;

function Component() {
  // コンポーネントとして、そのまま使用可能
  return <StyledButton> ログイン </StyledButton>;
}

JS と同じ場所に CSS の記述がされているのがわかると思います。

少しだけ詳しく解説すると、

このコードでは、styled-componentsと呼ばれるCSS in JSのライブラリを用いています。

そして、4 行目でstyled-componentsの機能を使って、button要素に対して CSS を記述しています。

styledで作られたデザインはコンポーネントとして使用することができます。

また、CSS in JSにはもう一つ便利な機能があります。

それは、CSS に変数を渡すことができる点です。

例えば以下のような形です。

props.primary ? "palevioletred" : "white"}; color: ${props => props.primary ? "white" : "palevioletred"}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; function Component() { // "primary"という引数をtrueとしてButtonに渡す return ; } ">
// "props"の中に引数が格納される
// 引数の値によってCSSを制御できる
const Button = styled.button`
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

function Component() {
  // "primary"という引数をtrueとしてButtonに渡す
  return <Button primary={true}> ログイン </Button>;
}

CSS でデザインされたコンポーネントに対して、簡単に引数を渡し、デザインを変更することができるのがCSS in JSの特徴です。

  • 結局どれ使えばいいんですか??

ここまで、たくさんの React のデザインの方法について見てきました。

では、このたくさんあるデザインシステムの中からどれを採用していけばいいのでしょうか?

まず、初めに考えるべきことは、アプリケーションの目的です。

アプリ開発にはその目的に応じて様々な制約が課せられるものです。

短い期間での開発が必要か?
既に大きなデザインシステムを使っているアプリのリプレイスか?
独自のデザインスシテムの運用が必要か?
どのようなエンジニアが集まっているか?

その中で、一番最適なデザインの方法を考えることがあなたにとってのベストプラクティスです。

例えば私の場合、開発しているアプリのデザインシステムを考えるときに「最速でいい感じのデザインを構築し、プロダクトの検証を素早く回さなければならない」と言う制約がありました。

つまり今回求められているのは、デザインの独自性や機能性ではなく、「触れるプロダクトをいかに早く構築するか」でした。

よって、デザインシステムを選ぶときも、いい感じのデザインがたくさんあり、かつ開発スピードが速くなるようなデザインシステムと言う要件を満たす「Meterial-UI」を採用しました。

このような形で、自身の置かれている状況や環境に合わせて柔軟にどのデザインシステムを採用するかを決めていく必要があります。

  • 今回の ReactBootcamp では「CSS モジュール」を使用

今回の ReactBootcamp では、CSSモジュールを使ったデザインシステムを構築していきたいと思います。

CSS モジュールを採用する理由は以下の通りです。

  • デザインを構築するのに CSS 以上の知識が必要ない

CSS モジュールを使用する以上、CSS 以外の知識は必要あありません。

つまり、それだけシンプルにデザインを構築することが可能になります。

  • なるべく「生」のデザインにふれる

本来であれば、短期間で使えるアプリケーションを構築するには「UI フレームワーク」を採用するのが定石です。

しかし、今回はあえて一からデザインを作成することで、より深いレベルでのデザインの仕組みについて理解することを木 t 形としています。

  • ライブラリ特有のエラーや環境構築を必要としない

CSS モジュールは、こちらでお見せした通り、CSS ファイルさえあればすぐに始めることができます。

他のデイザンシステムのようにライブラリを入れると言ったことも無いので、エラーや構文などに悩まされることがありません。

なので、今回は CSS モジュールを使用したデザインシステムを採用します。

Youtube アプリの構築に必要なコンポーネントの設計

お待たせしました。

それでは、実際にアプリケーションのデザインを行なっていきましょう。

最初にコードを書いていく前に、どのようなデザインで、どのようなコンポーネントが必要そうかの見ていきます。

今回作成するデザインの完成形は以下の Figma 内に構築済みです。

https://www.figma.com/file/xWjQFqQLjDZttAbUhps2EJ/?node-id=0%3A1

これから上記のデザインを全て構築していきます。

  • コンポーネントの設計に必要な考え方

コードを書いていくときに、ただ闇雲にデザインをコードに落とし込んで行っては、非常に開発のしずらいソースコードを生んでしまいます。

そこで、コンポーネントの設計を行うことで、わかりやすく、開発のしやすいコードを書いていくようにしていきます。

コンポーネントの設計に必要な考え方はシンプルです。

それは「デザインを共通化して、なるべくコードを書かなくて済むようなコンポーネントを作成する」ことです。

これがどう言うことか、見ていきましょう。

下記のデザインをまず見てください。

これは、アプリのHomeとなるページのデザインです。

React Youtube Home

例えばこのデザインでは、わかりやすく同じようなデザインが繰り返し使われていることが見て取れます。

これは、コンポーネントとして共通化して使い回しできるようにコードを書くべきですね。

React Youtube Home Card

他にも、ページごとのデザインを見てみると、ここにも繰り返しデザインが現れています。

React Youtube Page

例えば、ページ上部のHeaderを共通化できそうです。

また他にも、Sidebarの共通化も行えそうですね。

このような形で、デザイン全体を見たときに、コンポーネントとして共通化できそうなデザインを抽出して、積極的にコンポーネント化していきます。

  • ディレクトリ構造

上記で共通化したコンポーネントを実際に記述していくファイルを作成するには、フォルダ(ディレクトリ)で構造化することで、開発をしやすくすることができます。

しかし、残念ながら React にはどのようにディレクトリを作成すればいいか、というルールは存在しません。

よって、どのような形でディレクトリを構造化していくかは全て開発者に委ねられています。

React の開発者の間では、どのようなディレクトリ構造にするのがいいのかの議論は活発にされています。

ネットで検索してもたくさんのアイディアを見つけることができます。

その中で、今回はAtomic Desginと呼ばれるデザイン手法を改良したものを取り入れていきたいと思います。

具体的なディレクトリ構造は以下のような形で開発をしていきます。

src
├── Route.tsx
├── index.tsx
├── compoennts
│   └── [Component Name]
│       └── index.tsx
│       └── style.module.css
├── layouts
│   └── [Layout Name]
│       └── index.tsx
│       └── style.module.css
├── pages
│   └── [Page Name]
│       └── index.tsx
│       └── [Component Name]
│           └── index.tsx
│           └── style.module.css
└── templates
    └── [Template Name]
        └── index.tsx
        └── style.module.css

Route.tsx

アプリケーションのルーティング処理を記述します。

index.tsx

アプリケーションのエントリーポイントです。

必需品。

components

汎用的に使用できるコンポーネントです。

ここでは、ロジックを記述指定はいけません。

例えば、データベースとの非同期通信や、アプリケーション内のデータの fetch を行なってはいけません。

データは全て、親コンポーネントから受けもらいます。

※ただし、そのコンポーネント内で閉じているデータは、例外的にcomponents内で作成できます。

layouts

ページのレイアウトデザインのためのコンポーネントです。

ページ全体でのデザインのレイアウトを共通化します。

pages

特定のルーティングの Root となるコンポーネントです。

例えば、/loginと言うルーディングに対して、Loginと言うコンポーネントを作成して、/loginのルーティングで必要なコンポーネントやロジックを呼び出します。

また、そのpage内でしか呼び出さないロジック(非同期通信など)群を持ったコンポーネントは、子階層に作成していく。

templates

ロジック(非同期通信など)群を持ったコンポーネントです。

汎用的に使えるロジック群を持ったコンポーネントはここに作成します。

  • ロジックを持たない汎用コンポーネント →components
  • ロジックを持つ汎用コンポーネント →templates
  • 特定の page でのロジックを持つコンポーネント →pages

と言うルールのもと、ディレクトリを分けていきます。

必要ライブラリーのインストール

開発に必要なライブラリーのインストールを行います。

合わせてsrcのディレクトリ内を以下のような構造になるように、不要なファイルを削除し、新たにディレクトリとファイル(.tsx ファイル)を作成してください。

├── Route.tsx
├── compoennts/
├── layouts/
├── index.tsx
├── pages/
└── templates/

「まとめてインストール」を使用すれば今回の勉強会で必要なライブラリを全てインストールすることができます。

  • まとめてインストール用
npm install [email protected] @types/react-router-dom history
  • 個別インストール用

ルーティング用ライブラリ

@nextをつけることで、最新ベータ版をインストールできます。

react-router-dom最新ベータ版(v6.0.0-beta.1)では非常に便利な機能が追加されており、ベータ版ですが今回の Bootcamp ではこのバージョンを使っていきます。

npm install [email protected] @types/[email protected] history

デザインの前に、ルーティングを作成

まずは、URL を開いたときに、それぞれのパスで表示するコンポーネントを作成していきます。

ルーティングには、react-router-domを使用していきます。

まずは、Route.tsxを以下のように記述します。

{ // useRoutesを使用することで、ルーティング用のコンポーネントをいい感じにライブラリが作成してくれる // v6.0.0-beta.1から追加された便利機能 return useRoutes([ // HeaderとSidebarがあるデザインのページ // elementに指定したコンポーネントをページのレイアウトデザインとして使用する { element: , // childrenでは、pathに指定したURLで、使用するコンポーネントを指定する children: [{ path: "/", element:
Home
}], }, // Headerのみのデザインのページ { element: , children: [{ path: "watch/:videId", element:
watch
}], }, // HeaderもSidebarもないページのデザイン { element: , children: [ { path: "login", element:
ログイン
}, { path: "signup", element:
新規作成
}, { path: "forget", element:
パスワードリセット
}, { path: "404", element:
Not Found
}, // pathに"*"を指定することで、「全て」のURLとして指定する // Navigateを指定することで、リダイレクト処理 { path: "*", element: }, ], }, { path: "*", element: }, ]); }; ">
import { Navigate, useRoutes } from "react-router-dom";

// 下記のファイルはまだ作成されていないので、次項で作成する。
import { HomeLayout } from "./layouts/Home";
import { SideLessHomeLayout } from "./layouts/SideLessHome";
import { SimpleLayout } from "./layouts/Simple";

export const RootRouter = () => {
  // useRoutesを使用することで、ルーティング用のコンポーネントをいい感じにライブラリが作成してくれる
  // v6.0.0-beta.1から追加された便利機能
  return useRoutes([

    // HeaderとSidebarがあるデザインのページ
    // elementに指定したコンポーネントをページのレイアウトデザインとして使用する

    {
      element: <HomeLayout />,

      // childrenでは、pathに指定したURLで、使用するコンポーネントを指定する
      children: [{ path: "/", element: <div>Home</div> }],
    },

    // Headerのみのデザインのページ
    {
      element: <SideLessHomeLayout />,
      children: [{ path: "watch/:videId", element: <div>watch</div> }],
    },

    // HeaderもSidebarもないページのデザイン
    {
      element: <SimpleLayout />,
      children: [
        { path: "login", element: <div>ログイン</div> },
        { path: "signup", element: <div>新規作成</div> },
        { path: "forget", element: <div>パスワードリセット</div> },
        { path: "404", element: <div>Not Found</div> },

        // pathに"*"を指定することで、「全て」のURLとして指定する
        // Navigateを指定することで、リダイレクト処理
        { path: "*", element: <Navigate to="/404" /> },
      ],
    },
    { path: "*", element: <Navigate to="/404" /> },
  ]);
};

layoutsコンポーネントをまだ作成できいないので、作成します。

{ return (

Dashboard

{/* を配置した箇所に、childrenコンポーネントが展開される childrenコンポーネントとは、Route.tsx内でchildren>elementで指定したコンポーネントである */}
); }; ">
// src/layouts/Home/index.tsx と言うファイルを作成する
// 以下は、index.tsxのコード
import { Outlet } from "react-router-dom";

export const HomeLayout = () => {
  return (
    <div>
      <h1>Dashboard</h1>
      {/*
        を配置した箇所に、childrenコンポーネントが展開される
        childrenコンポーネントとは、Route.tsx内でchildren>elementで指定したコンポーネントである
      */}
      <Outlet />
    </div>
  );
};
{ return (

Dashboard

); }; ">
// src/layouts/SideLessHome/index.tsx と言うファイルを作成する
// 以下は、index.tsxのコード

import { Outlet } from "react-router-dom";

export const SideLessHomeLayout = () => {
  return (
    <div>
      <h1>Dashboard</h1>
      <Outlet />
    </div>
  );
};
{ return (

Simple

); }; ">
// src/layouts/Simple/index.tsx と言うファイルを作成する
// 以下は、index.tsxのコード
import { Outlet } from "react-router-dom";

export const SimpleLayout = () => {
  return (
    <div>
      <h1>Simple</h1>
      <Outlet />
    </div>
  );
};

最後に、index.tsxに以下のコードを追加する。

{/* この位置にを挿入する これにより、react-router-domが初期化され、アプリケーションでreact-router-domが使用できるようになる */} , document.getElementById("root") ); ">
import React from "react";
import ReactDOM from "react-dom";
// BrowserRouterをインポート
import { BrowserRouter } from "react-router-dom";
import { RootRouter } from "./Route";

ReactDOM.render(
  <React.StrictMode>
    {/*
      この位置にを挿入する
      これにより、react-router-domが初期化され、アプリケーションでreact-router-domが使用できるようになる
    */}
    <BrowserRouter>
      <RootRouter />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

ここまでで、一度全てのファイルを保存して、npm startで React を起動してみましょう。

下記のようになれば成功です。

React Router Dom

上部のアドレスバーの URL を/watch/loginに変更して見てください。

画面の表示も変わっているのがわかると思います。

Header のデザインを作成

Sidebar のデザイン作成

ビデオカードのデザイン作成

動画再生画面のデザイン作成

動画アップロード画面のデザイン作成

認証画面のデザイン作成

Issues
  • Specify movie file name in README

    Specify movie file name in README

    テスト用の動画をダウンロードする際、デフォルトではファイル名が production ID 4763824.mp4 となるため、そのまま public/static に動画を配置しても、動画は表示されません。

    動画のファイル名の変更を明記した方が分かりやすくなる気がするので、READMEの変更をご検討頂ければと思います。

    opened by poyopoyo0 2
  • bootcamp-4/source:Watchでリコメンドの動画一覧表示サムネイルの配置が乱れている

    bootcamp-4/source:Watchでリコメンドの動画一覧表示サムネイルの配置が乱れている

    react-bootcamp/src/pages/Watch/index.tsx <Grid>{recomendVideos?.video.map((vide) => { の入子が逆転しているので、2番目以降のサムネイルが再生動画の下部分に表示されます。

    opened by hiszuk 1
  • Fix typo and others

    Fix typo and others

    READMEに書かれているコードだと動かないところがありましたので、プルリクを出させて頂きます。ご確認下さい。

    opened by poyopoyo0 0
  • Fix typo to correspond to #2

    Fix typo to correspond to #2

    #2 の修正をサンプルコードにも適用した他、READMEで変換ミスと思われる箇所を修正させて頂きました。 ご確認お願いいたします!

    opened by poyopoyo0 0
  • Bootcamp 2

    Bootcamp 2

    merge bootcamp-2 into the master

    opened by Hiro-mackay 0
  • Fix typo to correspond to #3

    Fix typo to correspond to #3

    認証画面のデザイン作成 の確認用コードが動かなくなっていたので、 #3 の修正をこちらにも反映させて頂きました。 ご確認お願いいたします。

    opened by poyopoyo0 0
  • Fix typo in README

    Fix typo in README

    typoと思われる箇所を修正させて頂きました。ご確認下さい。

    opened by poyopoyo0 0
  • merge bootcamp 3

    merge bootcamp 3

    null

    opened by Hiro-mackay 0
  • Ubunt OSでの環境構築手順をまとめてみました。

    Ubunt OSでの環境構築手順をまとめてみました。

    @Hiro-mackay 簡易ではありますが、Ubunt OSでの環境構築手順をまとめてみました。

    Ubuntuの方はこちら

    UbuntuOS の方は、以下のパッケージをにインストールすることで、簡単に React の環境を構築することができます。

    • curl (HTTPアクセスをしてコンテンツを取得できるコマンドです)
    • nvm (Node.js をインストールし、バージョン管理できる)
    • node.js (nvm を通してインストール)
      • npm (上記インストールで自動でインストール)

    1.curlのインストール

    #コマンド
    sudo apt install -y curl
    

    sudoパスワードを要求された場合は、入力します。

    2. nvmスクリプトのダウンロード

    下記の URL にアクセスして、インストールスクリプトをダウンロードします。2021/08/13 現在、v0.38.0が最新バージョンです。

    nvm - Github

    #コマンド
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
    

    .bashrcファイルをソースします。

    #コマンド
    source ~/.bashrc
    

    3.Node.jsのインストール

    #今回は最新版v16.6.1の`Node.js`をインストールします。
    nvm install 16.6.1
    

    Node.jsのインストールが完了したら、以下のコマンドで指定のバージョンのNode.jsがインストールされているか確認します。

    #コマンド
    node -v
    
    #出力
    v16.6.1
    

    また、Node.jsをインストールすると勝手にnpmと言うパッケージがインストールされます。

    こちらは React 開発で非常に重要なパッケージですので合わせて確認しましょう。

    #コマンド
    npm -v
    
    #出力
    7.20.3
    
    opened by mendelssohnbach 3
React ESI: Blazing-fast Server-Side Rendering for React and Next.js

React ESI: Blazing-fast Server-Side Rendering for React and Next.js React ESI is a super powerful cache library for vanilla React and Next.js applicat

Kévin Dunglas 592 Nov 24, 2021
30 Days of React challenge is a step by step guide to learn React in 30 days

30 Days of React challenge is a step by step guide to learn React in 30 days. It requires HTML, CSS, and JavaScript knowledge. You should be comfortable with JavaScript before you start to React. If you are not comfortable with JavaScript check out 30DaysOfJavaScript. This is a continuation of 30 Days Of JS. This challenge may take up to 100 days, follow your own pace.

Asabeneh 8.6k Nov 28, 2021
React Navigation for React js that tries to ensure that the elements of the navigators display correctly on devices with notches and UI elements which may overlap the app content.

React Navigation for React js that tries to ensure that the elements of the navigators display correctly on devices with notches (e.g. iPhone X) and UI elements which may overlap the app content.

MohammadAli Karimi 11 Nov 18, 2021
React People lists and connects React developers around the world.

React People React People lists and connects React developers around the world. Progress View the Project page for details on what's planned and what'

Vitor Leonel 14 Aug 21, 2020
React Backbone Binding that works with React 16

WithBackbone React Higher Order Component which will bind Backbone Data that works with React Fiber (v.16) Why did we make it There are already a coup

Beanworks 2 Mar 19, 2021
A description of React's new core algorithm, React Fiber

React Fiber Architecture Introduction React Fiber is an ongoing reimplementation of React's core algorithm. It is the culmination of over two years of

Andrew Clark 9.1k Dec 1, 2021
React Clone - How React Works: An In-Depth Guide

Как работает React: подробное руководство Привет, друзья! В этой статье я покажу вам, с чего начинается React. Что это означает? Это означает, что мы

Igor Agapov 5 Nov 25, 2021
A drum machine built with React using the Create React App toolchain.

drum-machine A simple drum machine built with React using the Create React App toolchain. Getting Started Clone or download the repository. Open a com

Ryan Schafer 1 Nov 25, 2021
User-friendly query builder for React

react-awesome-query-builder User-friendly React component to build queries. Inspired by jQuery QueryBuilder Using awesome Ant Design v4 for widgets No

Denis Oblogin 1k Dec 2, 2021
React component to blur image backgrounds using canvas.

React Blur React component for creating blurred backgrounds using canvas. Live demo Installation npm install react-blur --save Usage var Blur = requir

Javier Bórquez 427 Nov 26, 2021
📑 A React component to easily create demos of other components

React DemoTab ?? A React component to easily create demos of other components Install npm install react-demo-tab Demo DemoTab example Example import R

mkosir 24 Nov 9, 2021
A React component to view a PDF document

React PDF viewer A React component to view a PDF document. It's written in TypeScript, and powered by React hooks completely. // Core viewer import {

React PDF Viewer 693 Nov 23, 2021
React file input component for complete control over styling and abstraction from file reading.

react-file-reader-input React file input component for complete control over styling and abstraction from file reading. <FileReaderInput as={dataForma

Kevin Ngo 110 Aug 24, 2021
The react UI component for building complex filter criteria

React Filter Control The React component for building the composite filter criteria Demo (JS) | Demo (TS) Together With Data Table Overview Installati

Alexander Komarov 29 Jul 24, 2021
React JSON Viewer Component, Extracted from redux-devtools

This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and pull requests. react-json-tre

Alexander Kuznetsov 988 Nov 22, 2021
🖱 A resizable and draggable component for React.

A resizable and draggable component for React. Table of Contents Screenshot Live Demo Storybook CodeSandbox Install Usage Props Instance API updateSiz

bokuweb 2.5k Dec 2, 2021
📏 A resizable component for React.

?? A resizable component for React. Table of Contents Screenshot Live Demo Storybook CodeSandbox Install Usage Props Instance API updateSize(size: { w

bokuweb 1.6k Nov 30, 2021
React split-pane component

React Split Pane Split-Pane React component, can be nested or split vertically or horizontally! Installing npm install react-split-pane # or if you u

tomkp 2.6k Nov 26, 2021
A simple React component to reproduce the way iOS deletes an item in a list

react-swipe-to-delete-ios A simple React component to reproduce the way iOS deletes an item in a list. Demo Installation yarn add react-swipe-to-delet

Arnaud Ambroselli 26 Nov 14, 2021