6
7

More than 3 years have passed since last update.

Reactの身内向けチュートリアル(その2)

Last updated at Posted at 2019-11-14

Vue.全盛の中、社内メンバー向けのReactの簡単なチュートリアル。

シリーズ

その2の概要

  • Reactでトップナビゲーションのある普通のページを作る方法の習得
  • HeaderやFooter等の共通部分をパーツ化する方法の習得

最低限のレイアウトをしてみる

App.jsをいじってそれっぽいレイアウトにしてみます。

なお、デフォルトで生成されるコードは関数コンポーネントですが、Redux等を利用することを想定しclassコンポーネントに変更しています。

App.js

App.js
import React from 'react';

class App extends React.Component {
     render() {
          return (
               <div>
                    <nav style={{ background: "#666" }}>
                         <ul style={{ display: 'flex', listStyle: 'none' }}>
                              <li style={{ margin: 10 }}><a href="/" style={{ color: "#fff", textDecoration: 'none' }}>Home</a></li>
                              <li style={{ margin: 10 }}><a href="/about" style={{ color: "#fff", textDecoration: 'none' }}>About</a></li>
                         </ul>
                    </nav>

                    <header style={{ height: 200, background: "#ddd" }}>
                         header
               </header>

                    <div id="main" style={{ height: 300, background: "#eee" }}>
                         main
               </div>

                    <footer style={{ height: 100, background: "#666", color: "#fff" }}>
                         footer
               </footer>
               </div>
          );
     }
}

export default App;

動作確認してみます。

yarn start

下記のような画面が表示されればOKです。

スクリーンショット 2019-11-14 12.00.37.png

ルーティング(ページ移動)の設定

ナビゲーションをクリックしても何も起こりません。それぞれHomeやAbout画面が表示されるようにしていきます。
ただ、create-react-appで作成できるアプリ?は基本SPA(Single Page Application)であるため、ページは1ページしかありません。なので通常のHTMLによるWeb作成と異なり、ルーティングという手法でページ移動を行います(ページはあくまで1ページで、移動しているように見せる)。

まず、ルーティングのためのライブラリをインストールします。react-routerというものが事実上の標準となっています。

yarn add react-router-dom

では、Home、Aboutそれぞれのページを作成してみます。
ここではApp.jsと同階層にscreensフォルダを作成し、その中にページ毎にHome.js, About.jsを作成していくようにしてみます。

ページの内容は上記で作成したApp.jsをベースに、クラス名や表示内容の一部を変更してみます。

screens/Home.js

まずはHome.js。

Home.js
import React from 'react';

+class Home extends React.Component {
     render() {
          return (
               <div>
                    <nav style={{ background: "#666" }}>
                         <ul style={{ display: 'flex', listStyle: 'none' }}>
                              <li style={{ margin: 10 }}><a href="/" style={{ color: "#fff", textDecoration: 'none' }}>Home</a></li>
                              <li style={{ margin: 10 }}><a href="/about" style={{ color: "#fff", textDecoration: 'none' }}>About</a></li>
                         </ul>
                    </nav>

                    <header style={{ height: 200, background: "#ddd" }}>
                         header
               </header>

                    <div id="main" style={{ height: 300, background: "#eee" }}>
+                         main(Home)
               </div>

                    <footer style={{ height: 100, background: "#666", color: "#fff" }}>
                         footer
               </footer>
               </div>
          );
     }
}

+export default Home;

screens/About.js

そして、About.js。

About.js
import React from 'react';

+class About extends React.Component {
     render() {
          return (
               <div>
                    <nav style={{ background: "#666" }}>
                         <ul style={{ display: 'flex', listStyle: 'none' }}>
                              <li style={{ margin: 10 }}><a href="/" style={{ color: "#fff", textDecoration: 'none' }}>Home</a></li>
                              <li style={{ margin: 10 }}><a href="/about" style={{ color: "#fff", textDecoration: 'none' }}>About</a></li>
                         </ul>
                    </nav>

                    <header style={{ height: 200, background: "#ddd" }}>
                         header
               </header>

                    <div id="main" style={{ height: 300, background: "#eee" }}>
+                         main(About)
               </div>

                    <footer style={{ height: 100, background: "#666", color: "#fff" }}>
                         footer
               </footer>
               </div>
          );
     }
}

+export default About;

App.js

Home.js, About.jsが準備できたら、App.jsの内容を変更しルーティングできるよう設定を行います。
各ページを読込、pathとページ(コンポーネント)をマッピングさせます。まあ、意味はわかると思います。

App.js
import React from 'react';
import { BrowserRouter, Route, Switch, NavLink } from 'react-router-dom';

//import screens
import Home from './screens/Home';
import About from './screens/About';

class App extends React.Component {
     render() {
          return (
               <BrowserRouter>
                    <Switch>
                         <Route exact path="/" component={Home} />
                         <Route exact path="/about" component={About} />
                         <Route render={() => (<p>Page not found.</p>)} />
                    </Switch>
               </BrowserRouter>
          );
     }
}

export default App;

動作確認する

yarn startさせ、動作を確認してください。

yarn start

Home, AboutをクリックするとURLおよびコンテンツ内容が変化しているはずです。
下記画面ではAboutボタンを押したら、コンテンツもAboutになっている。

スクリーンショット 2019-11-14 12.16.00.png

共通部品化する

上記の例ではHome.js, About.jsに重複したコードが書かれており非常に冗長です。Nav, Header, Footer等は共通化したいので、それを行います。
共通化のためには各部を切り出して個別のコンポーネントに(部品化)します。
screensの中に、各部を担うjsを作成していきます。

Nav.js(ナビゲーション部)

Nav.js
import React from 'react';

class Nav extends React.Component {
    render() {
        return (
            <nav style={{ background: "#666" }}>
                <ul style={{ display: 'flex', listStyle: 'none' }}>
                    <li style={{ margin: 10 }}><a href="/" style={{ color: "#fff", textDecoration: 'none' }}>Home</a></li>
                    <li style={{ margin: 10 }}><a href="/about" style={{ color: "#fff", textDecoration: 'none' }}>About</a></li>
                </ul>
            </nav>
        );
    }
}

export default Nav;

Header.js(ヘッダー部)

Header.js
import React from 'react';

class Header extends React.Component {
    render() {
        return (
            <header style={{ height: 200, background: "#ddd" }}>
                header
            </header>
        );
    }
}

export default Header;

HomeContent.js(Homeのコンテンツ部)

HomeContent.js
import React from 'react';

class HomeContent extends React.Component {
    render() {
        return (
            <div id="main" style={{ height: 300, background: "#eee" }}>
                HomeContent
            </div>

        );
    }
}

export default HomeContent;

AboutContent.js(Aboutのコンテンツ部)

AboutContent.js
import React from 'react';

class AboutContent extends React.Component {
    render() {
        return (
            <div id="main" style={{ height: 300, background: "#eee" }}>
                AboutContent
            </div>

        );
    }
}

export default AboutContent;

Footer.js(フッター部)

Footer.js
import React from 'react';

class Footer extends React.Component {
    render() {
        return (
            <footer style={{ height: 100, background: "#666", color: "#fff" }}>
                footer
            </footer>
        );
    }
}

export default Footer;

ここまでで各部のコンポーネント化が完了しました。ここからはHome.jsとAbout.jsを各パーツを利用するように変更します。

Home

まずはHome.jsの変更。

Home.js
import React from 'react';

//screens
import Nav from './Nav';
import Header from './Header';
import HomeContent from './HomeContent';
import Footer from './Footer';

class Home extends React.Component {
    render() {
        return (
            <React.Fragment>
                <Nav />
                <Header />
                <HomeContent />
                <Footer />
            </React.Fragment>
        );
    }
}

export default Home;

About

ほぼ同じですが、About.jsの変更。違いはコンテンツ部だけです。

About.js
import React from 'react';

//screens
import Nav from './Nav';
import Header from './Header';
import AboutContent from './AboutContent';
import Footer from './Footer';

class About extends React.Component {
    render() {
        return (
            <React.Fragment>
                <Nav />
                <Header />
                <AboutContent />
                <Footer />
            </React.Fragment>
        );
    }
}

export default About;

動作確認

yarn startさせ、動作を確認します。変更はレウアウトだけなので動作に変化は無いはずです。

Navを少し改良する

動作に問題はありませんんが、HomeにいるのかAboutにいるのかわかりにくいので、Navの文字色を変更してみます。
NavLinkを利用すれば、active時のクラスやスタイルを指定、変更することができるので利用してみます。

Nav.js
import React from 'react';
import { NavLink } from 'react-router-dom';

class Nav extends React.Component {
    render() {
        return (
            <nav style={{ background: "#666" }}>
                <ul style={{ display: 'flex', listStyle: 'none' }}>
                    <li style={{ margin: 10 }}><NavLink exact to="/" style={{ color: "#fff", textDecoration: 'none' }} activeStyle={{ color: '#aaf' }}>Home</NavLink></li>
                    <li style={{ margin: 10 }}><NavLink exact to="/about" style={{ color: "#fff", textDecoration: 'none' }} activeStyle={{ color: '#aaf' }}>About</NavLink></li>
                </ul>
            </nav>
        );
    }
}

export default Nav;

これにより、各ページにいるときのスタイルを変更できます。

スクリーンショット 2019-11-14 12.32.08.png

その2のおさらい

  • Reactで作成したSPAにてルーティングさせる方法がわかりました。
  • 共通部をパーツ化する方法がわかりました。

以上です。その3につづく。

6
7
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
6
7