LoginSignup
3
0

More than 5 years have passed since last update.

俺専用フロントエンドアプリひな型

Last updated at Posted at 2018-12-01

はじめに

WCDI Advent Calendar 2日目
前の人の記事
次の人の記事

ネタがないので俺専用React starterの俺専用解説を書く
https://github.com/NozomiSugiyama/react-material-starter

最適化しきってない(する予定もない)ので、参考にできるところがあったら参考にして、参考にならないところは自分で書き換えて使ってほしい

今回作成したのは
React + TypeScriptでMaterialデザインのWebApplicationのひな型である

使ってるもの

  1. React
  2. styled-components
  3. TypeScript
  4. Material-UI
  5. webpack-serve
  6. etc...

解説

ディレクトリ構成

  • assets(静的コンテンツ置き場)
  • src(JavaScriptのソース置き場)
    • api(RESTful APIの呼び出し関数などを配置することを想定)
    • components(Reactのコンポーネント置き場)
      • commons(依存性の低い汎用的に使うコンポーネント置き場)
      • pages(ページ用コンポーネント置き場)
      • wrappers(すべてのページコンポーネントにpropsを渡すためのwrapperコンポーネント置き場)
    • util(汎用的なコード置き場(通称なんでも置き場))

セットアップ

$ git clone git@github.com:NozomiSugiyama/react-material-starter.git
$ yarn

コマンド解説

$ yarn start

webpack-serve を使ってブラウザデバッグをサポート
ホットリロードしてくれる

$ yarn build:prod

Production用にビルドを行う

$ yarn lint

/src 下を対象にtslintを行う

※他のコマンド類は package.json を見るべし。サイズアナライズ機能とかDocumentジェネレートとかも一応用意してある

ページ追加

  1. /src/components/pages/ 以下にファイルを作成 (HogePage.tsx)
HogePage.tsx
import React from "react";
import { PageComponentProps } from "../../App";
import Page                   from "../commons/Page";

export default class WorkListPage extends React.Component<PageComponentProps> {
    render() {
        return (
            <Page>
                HogePage
            </Page>
        );
    }
}
  1. /src/components/NavigationBar.tsx を変更
NavigationBar.tsx
import React from "react";
import {
    Divider,
    List,
    ListItem,
    ListItemText,
    Typography,
    withTheme
} from "@material-ui/core";
import { TypographyProps } from "@material-ui/core/Typography";
import Link from "./commons/Link";
import styled from "styled-components";

export default (props: React.HTMLAttributes<HTMLElement>) => (
    <nav {...props}>
        <Toolbar>
            <Title>ServiceName</Title>
        </Toolbar>
        <Divider />
        <List>
            <Link
                to="/top"
            >
                <ListItem
                    button
                    selected={location.pathname === "/top" || location.pathname === "/"}
                >
                    <ListItemText
                        primary={"Top Page"}
                    />
                </ListItem>
            </Link>
            <Link
                to="/dashboard"
            >
                <ListItem
                    button
                    selected={location.pathname === "/dashboard"}
                >
                    <ListItemText
                        primary={"Dashboard"}
                    />
                </ListItem>
            </Link>
            <!-- 追加 ここから --> 
            <Link
                to="/hoge"
            >
                <ListItem
                    button
                    selected={location.pathname === "/hoge"}
                >
                    <ListItemText
                        primary={"Hoge"}
                    />
                </ListItem>
            </Link>
            <!-- 追加 ここまで --> 
        </List>
    </nav>
);
  1. /src/Routes.tsx に追加
Routes.tsx
export { default as DashboardPage } from "./components/pages/DashboardPage";
export { default as TopPage      } from "./components/pages/TopPage";
// 追加
export { default as HogePage      } from "./components/pages/HogePage";
  1. /src/App.tsx に追加
App.tsx
import React from "react";
import { createMuiTheme }   from "@material-ui/core/styles";
import { MuiThemeProvider } from "@material-ui/core";
import {
    BrowserRouter as Router,
    RouteComponentProps,
    match
} from "react-router-dom";
import ComposingRoute                from "./components/commons/ComposingRoute";
import ComposingSwitch               from "./components/commons/ComposingSwitch";
import { MainLayoutEventProps }      from "./components/wrappers/MainLayout";
import { NotificationListenerProps } from "./components/wrappers/NotificationListener";
import {
    DashboardPage,
    TopPage,
    // 追加
    HogePage
} from "./Routes";
import Root from "./Root";

export default () => (
    <MuiThemeProvider theme={theme}>
        <Router>
            <Root
                key="root"
            >
                <ComposingSwitch>
                    <ComposingRoute
                        path="/"
                        component={TopPage}
                        exact={true}
                    />
                    <ComposingRoute
                        path="/top"
                        component={TopPage}
                    />
                    <ComposingRoute
                        path="/dashboard"
                        component={DashboardPage}
                        exact={true}
                    />
                    <!-- 追加 -->
                    <ComposingRoute
                        path="/hoge"
                        component={DashboardPage}
                        exact={true}
                    />
                    <!-- 追加 -->
                </ComposingSwitch>
            </Root>
        </Router>
    </MuiThemeProvider>
);

Snackbarを用いた通知

Hoge.tsx
import React from "react";
import { PageComponentProps } from "../../App";
import Page                   from "../commons/Page";

export default class WorkListPage extends React.Component<PageComponentProps> {
    _notification() {
        this.props.notificationListener.notification("info", "通知内容");
    }

    render() {
        return (
            <Page>
                HogePage
                <button
                    onClick={this._notification}
                />
                    通知ボタン
                </button>
            </Page>
        );
    }
}

いいところ

オレオレを使うとやっぱり楽。作ってない人はまじで作るべき

つらいところ

styled-componentsのTypeScriptとReactのTypeScriptで喧嘩が激しい
バージョン上げると大体そこの修正が必要

3
0
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
0