Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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で喧嘩が激しい
バージョン上げると大体そこの修正が必要

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした