Vue.全盛の中、社内メンバー向けのReactの簡単なチュートリアル。
シリーズ
- その1:create-react-appの簡単な使い方とファイル構成
- その2:簡単なページの作成(共通パーツ化含む)とreact-routernによるルーティング(この記事)
- その3:簡易認証機能(ログイン・ログアウト)の追加
その2の概要
- Reactでトップナビゲーションのある普通のページを作る方法の習得
- HeaderやFooter等の共通部分をパーツ化する方法の習得
最低限のレイアウトをしてみる
App.jsをいじってそれっぽいレイアウトにしてみます。
なお、デフォルトで生成されるコードは関数コンポーネントですが、Redux等を利用することを想定しclassコンポーネントに変更しています。
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です。
ルーティング(ページ移動)の設定
ナビゲーションをクリックしても何も起こりません。それぞれ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。
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。
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とページ(コンポーネント)をマッピングさせます。まあ、意味はわかると思います。
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になっている。
共通部品化する
上記の例ではHome.js, About.jsに重複したコードが書かれており非常に冗長です。Nav, Header, Footer等は共通化したいので、それを行います。
共通化のためには各部を切り出して個別のコンポーネントに(部品化)します。
screensの中に、各部を担う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(ヘッダー部)
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のコンテンツ部)
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のコンテンツ部)
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(フッター部)
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の変更。
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の変更。違いはコンテンツ部だけです。
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時のクラスやスタイルを指定、変更することができるので利用してみます。
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;
これにより、各ページにいるときのスタイルを変更できます。
その2のおさらい
- Reactで作成したSPAにてルーティングさせる方法がわかりました。
- 共通部をパーツ化する方法がわかりました。
以上です。その3につづく。