はじめに
今回は簡単な日記アプリを作りながらReact RouterとEmotionを学んでいきます。
Routerを使った画面遷移
画面遷移1つだけですが・・・笑
実際に遷移する様子、ソースコードは以下を参照してください。
React Routerとは?
Reactのアプリケーションでルーティングを管理するライブラリです
複数ページのアプリケーションを作成する際に使用されます。
Linkを定義したり、Pathごとにレンダリングするコンポーネントを指定したり、ページ遷移する際の動作を提供したり様々な機能があります。
機能ありすぎて追いつかなかったので基本となるものだけ使っていきます。
React Routerのインストール
npm install react-router-dom
ルートディレクトリでこちらのコマンドを実行
Package.jsonのdependenciesに react-router-dom が追加されていればOKです
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.82",
"@types/react": "^18.2.56",
"@types/react-dom": "^18.2.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.1",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
ReactRouterの基本となるコンポーネント
React Routerが提供する機能を使用するためにはimportして必要なコンポーネントを取り出して使用します。
import { BrowserRouter ,Link, Routes, Route } from 'react-router-dom';
BrowserRouter
公式の説明が難しくてあまりわからない・・・
A stores the current location in the browser's address bar using clean URLs and navigates using the browser's built-in history stack.
ブラウザのアドレスバーにある現在地を保存したり履歴を使いながら操作してるってことなんだろうか。
詳しいことはわかりませんがルートコンポーネントに置くことでルーティング機能を有効してくれるようです。
これがないとRouterが提供する機能を使用できません。
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
このようにしてルートとなるコンポーネントを囲むように配置します。
Link
Linkタグを作成することができます。
toプロパティに指定したPathに遷移することができます。
今回はTOPページ、記事作成ページの2つだけなので、このように書きました。
<div className="App">
<nav css={navStyle}>
<Link to="/" css={linkStyle}>TOPページ</Link>
<Link to="/article" css={linkStyle}>記事作成</Link>
</nav>
宣言的ナビゲーションというようで、aタグとは違いページを全てリロードせずにレンダリングすることができます。
RoutesとRoute
この2つを使用してルーティングの設定を書いていきます。
仕組みとしては
Linkタグなどを押下し、URLが変更されたとき、Routesコンポーネント内に定義されたRouteの中から一致するpathを探します。
そうして一致したRouteコンポーネントのelementプロパティ内に指定されたコンポーネントをレンダリングしページ遷移を行います。
<Routes>
<Route path="/" element={<Home posts={posts} />} />
<Route path="/article" element={<ArticleCreation posts={posts} setPosts={setPosts} />} />
</Routes>
propsを渡したい時はelementプロパティ内で通常時と同様に渡すことができます。
element={<ArticleCreation posts={posts} setPosts={setPosts} />
routerで遷移を実行する流れ
- BrowserRouterでルーティング機能を有効に
- RoutesとRouteでルーティングの設定を行う
- LinkでRouteに対応するPathに遷移する
このような流れで実装できました。
ちなみに記事投稿時に別のページに遷移などしたい場合は
useNavigateというものを使用するようです。
今回は記事を投稿した時にHomeページへ遷移したかったので使用しました。
import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
navigate('/', { state: { message: '記事を投稿しました' } });
第1引数に渡したPathに遷移します。
第2引数には遷移先で表示したいmessageなど渡すことができます。
まだまだたくさんの機能があるので、このあたりは何かアプリでも作りながら、必要に応じて知っていきたいと思います。
Emotionとは
CSS-in-JSを提供するライブラリの1つです。
Styleをjavascriptで定義してコンポーネントに適用することができます。
使い方
ライブラリのインストール
npm install @emotion/react @emotion/styled
追加されていることを確認
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
ファイルの先頭にコメントを記述
/** @jsxImportSource @emotion/react */
これを記載することでEmotionが提供するStyle機能をjsxまたはtsxに適用できるようになります
cssコンポーネントを取り出し
このような書き方をします
import { css } from '@emotion/react';
const 変数名 = css`[cssの定義]`
実際に書いたのがこちら
import { css } from '@emotion/react';
export const homeTitle = css`
color: #333;
text-align: center;
margin-bottom: 20px;
`
export const container = css`
max-width: 800px;
margin: 40px auto;
padding: 20px;
background: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
`
export const title = css`
color: #007BFF;
font-size: 24px;
margin-bottom: 10px;
`
export const content = css`
color: #666;
line-height: 1.6;
`
export const item = css`
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
`
export const list = css`
list-style-type: none;
padding: 0;
`
Styleは別ファイルに切り出し
exportをつけることで
必要な場所で、必要な数だけ読み込んで使用することもできます。
Home.tsxではこのように使用しました。
cssプロパティに読み込んだ変数をセットすることで適用できます。
/** @jsxImportSource @emotion/react */
import { Post } from "../App";
import {container,homeTitle, list, item, title, content } from '../styles/HomeStyles';
interface HomeProps {
posts: Post[];
}
export const Home = (props: HomeProps) =>{
const {posts} = props;
return (
<div css={container}>
<h1 css={homeTitle}>日記一覧</h1>
<ul css={list}>
{posts.map((post) => (
<li css={item} key={post.id}>
<h2 css={title}>{post.title}</h2>
<p css={content}>{post.content}</p>
</li>
))}
</ul>
</div>
);
}
まとめ
以上RouterとEmotionの簡単な使い方と使用例でした!
ライブラリや機能が多すぎて理解が追いつかないですね・・
少しずつ複雑な機能等を取り入れたアプリも作成していく中で学んでいく必要がありそうです。