Next.jsの前にReact入門
Next.js × microCMSで個人ブログを作成する
そのためまずはNext.jsのチュートリアルサイトでReactの基礎学習を進める
Reactの3つのコア・コンセプト
Reactを扱ううえで、以下3つのコア・コンセプトを理解する必要がある。
- Components
- Props
- State
Components
コンポーネントは、ボタンのような小さなものである場合も、ページ全体を表す大きなものである場合もあります。
引用元:公式ドキュメント
画面に表示される1つ1つの部品のこと。
Reactの画面(UI)はComponentが集まってできている。
Component(部品)ごとにオブジェクトを作成するため、再利用することができる。
コンポーネントの構築手段は2つ存在する
- クラスコンポーネント
- 関数コンポーネント
クラスコンポーネント
Reactの初期のバージョンの頃に使用されていた方法
※関数コンポーネントが好まれている傾向があるように見えたので、触りだけ学んで詳細な書き方やコードについては飛ばす
メリット
- Reactが独自に提供する
React.Component
クラスを継承したJavaScriptクラスを使って生成される - オブジェクト指向的な構文があるため、OOP開発経験のあるものは馴染みやすい
デメリット
- 記述が冗長であり、コンポーネントの状態やライフサイクルメソッドの管理により複雑性が増す
- ES6のクラス構文を使用しているため、関数コンポーネントよりも読みづらい
参考サイト:
昔はクラスコンポーネントがよく使われていたらしいが、今は関数コンポーネント派が多いらしい。
じゃあなぜ関数コンポーネント派が増えたのか?
クラスコンポーネントでしか使えなかった以下の機能が関数コンポーネントでも使えるようになった。
- State
- Lyfecycle Hooks
React 16.8 で新たに追加されたHooksによって、これらを関数コンポーネントでも使えるようになった。
参考サイト:
関数コンポーネント
マークアップを返すJavaScriptコンポーネント
UIとなる部品ボタンをfunction MyButton() {}
で作成する。
でないと、Reactのコンポーネントとして認識されない。
returnでjsxで書かれた属性を返す。
function MyButton() {
return (
<button>I'm a button</button>
);
}
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
Props
HomePage()
からHeader()
を呼び出すときに引数へprops
を指定することで、プロパティをHeaderコンポーネントに渡すことができる。
function Header(props) {
return <h1>Develop. Preview. Ship.</h1>;
}
function HomePage() {
return (
<div>
<Header title="React" />
</div>
);
}
試しにコンソールに出力してみる
function Header(props) {
console.log(props);
return <h1>Develop. Preview. Ship.</h1>;
}
Headerの呼び出し元に書いたプロパティが出力されている
propsの型はオブジェクトであるため、デストラクチャリングを使用することができるそう。
この記事が参考になった
PHPのlist()とは少し違うよう。
<script type="text/jsx">
const app = document.getElementById("app")
function Header({ title,name }) {
console.log(title);
console.log(name);
return <h1>Develop. Preview. Ship.</h1>;
}
function HomePage() {
return (
<div>
<Header title="React" name="headerName" />
</div>
)
}
const root = ReactDOM.createRoot(app);
root.render(<HomePage />);
</script>
こうすることで、条件によってレンダリング対象を切り替えることできるそう
function Header({title}) {
return <h1>{title}</h1>;
}
function HomePage() {
return (
<div>
<Header title="React" />
</div>
)
}
他にも手段があるそう
1. ドット表記のオブジェクト・プロパティ
function Header(props) {
return <h1>{props.title}</h1>;
}
2. テンプレート・リテラル
${title}
で表記するときは、必ずシングルクォートではなく、バッククォートを使うように注意する
function Header({ title }) {
return <h1>{`Cool ${title} Literal`}</h1>;
}
3. 関数の戻り値
titleプロパティの設定値判定条件をいれて表示する内容を切り替えている。
function createTitle(title) {
if (title) {
return title;
} else {
return 'Default Title';
}
}
function Header({title}) {
return <h1>{createTitle(title)}</h1>
}
function HomePage() {
return (
<div>
<Header title="React" />
</div>
)
}
titleプロパティの値が入っていたらtrue
つまり画面に「React」と表示される。
titleプロパティが空であればfalse
つまり、画面に「Default Title」と表示される。
4. 三項演算子
3ではIF文で分岐していたが、三項演算子で表現する方法もある
function Header({ title }) {
return <h1>{title ? title : 'Default Title'}</h1>;
}
Iterating through lists
リストの内容をforのように回してレンダリングする方法
同じスタイル(表示の仕方)で異なる情報を保持するUI要素を作成する
array.map()
array名.map()
とし、mapのなかで(key)=>(value)の書き方で配列の各要素を表示できる
function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
</div>
);
}
If you run this code, React will give us a warning about a missing key prop. This is because React needs something to uniquely identify items in an array so it knows which elements to update in the DOM.
訳
このコードを実行すると、Reactはキー・プロップが見つからないという警告を出す。これは、ReactがDOMのどの要素を更新すべきかを知るために、配列のアイテムを一意に識別する何かが必要だからです。
引用元
{names.map((name) => (
<li key={name}>{name}</li>
))}
ボタンをクリックした時に動作させたいロジックはonClick
イベントで呼び出す
function HomePage() {
function handleClick() {
console.log("increment like count");
}
return (
<div>
<button onClick={handleClick}>Like</button>
</div>
)
}
State
state
を使うことで、ボタンをクリックした回数などを保持することができる。
例:いいねボタンのいいね数
Hooksの機能を使うことで、実装することができ、名前はuseState()
という。
- 空の配列として
useState()
を初期化する
今回は初期値としてuseState()
に「0」を入れておく
※必ずしも入れる必要はない
function HomePage() {
const [] = React.useState(0);
}
- state名をつける
配列の1番目の項目にstate名をつける。名前はなんでもOKらしい。
言わずもがな何を表しているかが誰でも判断できる範囲ならOKだということ。
今回はいいね数を例としているため、likes
にする。
function HomePage() {
const [likes] = React.useState(0);
}
- 更新名をつける
配列の2番目に対象の値を更新する際に使う関数名を書く。
基本的に名前はなんでもOKだが、名称の前に「set」をつけること。
一般的には配列の1番目の名前をsetの後ろにくっつけるそう。
ちなみにキャメルケースで命名すること
function HomePage() {
const [likes, setLikes] = React.useState(0);
}
完成品がこちら
コードはこちら
<html>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- Babel Script -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/jsx">
const app = document.getElementById("app")
function createTitle(title) {
if (title) {
return title;
} else {
return 'Default Title';
}
}
function Header({title}) {
return <h1>{createTitle(title)}</h1>
}
function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
const [likes, setLikes] = React.useState(0);
function handleClick() {
setLikes(likes + 1);
}
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<button onClick={handleClick}>Like({likes})</button>
</div>
)
}
const root = ReactDOM.createRoot(app);
root.render(<HomePage />);
</script>
</body>
</html>
Next.jsについて学ぶ
Reactの3つの基本概念について大体理解したからNext.jsの章に進む
package.json
とindex.html
を作成してコマンド実行
npm install react@latest react-dom@latest next@latest
エラー発生
エラー文読む感じpackage.jsonファイルが悪そう
package.json
の中に以下を記載
{}
ファイルを保存してもう一度コマンド実行したら成功した。
Reactプロジェクトを作成したら、フロントエンドのビルド機能を使うためにpackage.json
に以下を追加する
こうすることで、ターミナルでnpm run dev
と実行することで開発用サーバーが立ち上がる
{
// ここから
"scripts": {
"dev": "next dev"
},
// ここまで
"dependencies": {
"next": "^14.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
部品を再利用する
いいねボタンを部品化して簡単に再利用できるようにする
app/like-button.js
を作成していいねボタンのコードを入力
'use client';
import { useState } from "react";
const [likes, setLikes] = useState(0);
export default function LikeButton() {
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>
}
埋め込みたいページで対象のコンポーネント(今回はLikeButton)をpage.js
でimportして使う
てことでlike-button.js
内の関数LikeButton
をpage.js
へimportする
<コンポーネント名 />
とすることで再利用可能となる
import LikeButton from "./like-button"
function Header({ title }) {
return <h1>{title ? title : "Default title"}</h1>
}
export default function HomePage() {
const names = ["Ada Lovelace", "Grace Hopper", "Margaret Hamilton"]
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<LikeButton />
</div>
)
}