元営業WEBエンジニアのアプリ開発日記

営業出身のWEB系エンジニアが気になったものから作ってはメモを残してくブログ

ReactのUI部分だけ作成(Routing含む)

概要

Reactでアプリ作ってみる。
Stateの管理はReduxを使いたいのでThinking in React – ReactのUI部分までにしとく

Start With A Mock

Mockを考えるらしい。
SpringBootとGraphQLで素敵なAPI作成 - 元営業WEBエンジニアのアプリ開発日記では「会員追加」と「名前で会員取得」の2API作ったのでこれが動くMockを考えるとこんな感じかな  f:id:shintaro-0112:20180828221149p:plain f:id:shintaro-0112:20180828221155p:plain

Break The UI Into A Component Hierarchy

UIをComponent単位で分割するらしい。
上の絵の色付きの四角が何となく分割してみたComponent

UIの動きだけでも作ってみる

必要なパッケージをインストール

ブラウザ上で戻るとかできるようにhistory, Routing関連実現するのにreact-router-dom

npm install --save history
npm install --save react-router-dom

インデックスファイルの修正

  • <Router history={hist}>でブラウザで戻ったり進んだりできる
  • <Switch>いれるとヒットしたコンポーネントを描画(それ以降のRouteは見ない)

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import { createBrowserHistory } from "history";
import { Router, Route, Switch } from "react-router-dom";
import indexRoutes from "./routes/index";

const hist = createBrowserHistory();

ReactDOM.render(
    <Router history={hist}>
        <Switch>
            {indexRoutes.map((prop, key) => {
                return <Route path={prop.path} component={prop.component} key={key} />;
            })}
        </Switch>
    </Router>,
    document.getElementById('root'));
registerServiceWorker();

ルーティングの大元作成

src/routes/index.jsx

import Future from "../layouts/future/Future";

const indexRoutes = [{ path: "/", component: Future }];

export default indexRoutes;

①全ページ共通のレイアウト作成

  • futureRoutesに記載されたルーティング一覧を読み込む

/src/layouts/future/Future.jsx

import React from "react";
import { Switch, Route, Link } from "react-router-dom";
import futureRoutes from "../../routes/future";

const switchRoutes = (
    <Switch>
        {futureRoutes.map((prop, key) => {
            return <Route path={prop.path} component={prop.component} key={key} />;
        })}
    </Switch>
);

class App extends React.Component {
    render() {
        return (
            <div>
                <div>
                    <div><b>Link</b></div>
                    <li><Link to="/search_member">SearchMember</Link></li>
                    <li><Link to="/regist_member">RegistMember</Link></li>
                </div>
                <div>
                    <div>{switchRoutes}</div>
                </div>
            </div>
        );
    }
}

export default App;

ルーティング一覧の記載

/src/routes/future.jsx

import SearchMember from "../views/SearchMember/SearchMember.jsx";
import RegistMember from "../views/RegistMember/RegistMember";

const futureRoutes = [
    {
        path: "/search_member",
        component: SearchMember
    },
    {
        path: "/regist_member",
        component: RegistMember
    }
];

export default futureRoutes;

SearchMemberページの作成

②大枠の作成

/src/views/SearchMember/SearchMember.jsx

import React from "react";
import SearchByNameBar from "../../components/SearchByNameBar";
import MemberTable from "../../components/MemberTable";

function SearchMember({ ...props }) {
    return (
        <div>
            <p><b>SearchMember</b></p>
            <SearchByNameBar />
            <MemberTable />
        </div>
    );
}

export default SearchMember;

③検索部分

このsubmitボタンクリックで検索APIを呼び出す予定

/src/components/SearchByNameBar.jsx

import React from "react";

function SearchByNameBar({ ...props }) {
    return (
        <form>
            <div>
                Name  <input type="text" />  <input type="submit" value="Search" />
            </div>
            <p>※PerfectMatchingOnly</p>
        </form>
    );
}

export default SearchByNameBar;

⑧検索結果部分

  • <tbody>内をAPIで取得した会員一覧ループさせ予定
  • API呼び出し時にLoading, エラーの場合メッセージ表示とかしたい

/src/components/MemberTable.jsx

import React from "react";
import MemberRow from "../components/MemberRow";

function MemberTable({ ...props }) {
    return (
        <table>
            <thead>
                <tr>
                    <th>id</th>
                    <th>name</th>
                    <th>createdAt</th>
                    <th>updatedAt</th>
                </tr>
            </thead>
            <tbody>
                <MemberRow />
                <MemberRow />
            </tbody>
        </table>
    );
}

export default MemberTable;

⑨検索会員レコード

/src/components/MemberRow.jsx

import React from "react";

function MemberRow({ ...props }) {
    return (
        <tr>
            <td>1</td>
            <td>testName</td>
            <td>2018-08-28T10:00:00</td>
            <td>2018-08-28T10:00:00</td>
        </tr>
    );
}

export default MemberRow;

RegistMemberページの作成

②大枠の作成

/src/views/RegistMember/RegistMember.jsx

import React from "react";
import RegistNameBar from "../../components/RegistNameBar";
import RegistNameResult from "../../components/RegistNameResult";

function RegistMember({ ...props }) {
    return (
        <div>
            <p><b>RegistMember</b></p>
            <RegistNameBar />
            <RegistNameResult />
        </div>
    );
}

export default RegistMember;

③登録フォーム

検索と同様submitすると登録API呼び出したい

/src/components/RegistNameBar.jsx

import React from "react";

function RegistNameBar({ ...props }) {
    return (
        <form>
            <div>
                Name  <input type="text" />  <input type="submit" value="Regist" />
            </div>
        </form>
    );
}

export default RegistNameBar;

⑥登録結果エリア

APIのレスポンスに応じて個々の表示出し分け予定

/src/components/RegistNameResult.jsx

import React from "react";

function RegistNameResult({ ...props }) {
    return (
        <div>Regist Success!!</div>
    );
}

export default RegistNameResult;

まとめ

もう完全に気力がなくなってきたw
Githubの対象コミットとか貼り付けときゃ良いんじゃないか説が浮上してきた-_-