[やり直し]やり直し体験(w/create-next-app)


👉 Next.js


Next.jsはreactを作成するフレームワークの1つであり、reactのみを作成するアプリケーションとは異なり、サーバ側は基本的に管理されています.
reactのみで構成されるアプリケーションに比べて、ルーティングが簡単でapi呼び出し機能が内蔵されているのが利点です.

👉 スタート


react appと同じようにNext.jsを使用したappも開発ツールをサポートしています.
$> npx create-next-app app이름
上記のコマンドを入力すると、自動的にNextが生成されます.js appを生成します.
プロジェクトの作成が完了すると、次のファイルが作成されていることがわかります.
生成されたファイルのインデックス.jsファイルが起動ファイルでappを実行してルートエンドポイントにアクセスすると、画面に表示されるページ構造はindexです.jsに書かれた値.
JavaScriptで作ったアプリNextなのでjs appもreact appパッケージと同じです.jsonは存在し、内部にはnpmコマンドスクリプトが存在します.
生成されたベースアイテムは、次のコマンドを使用して実行できます.
$> npm run dev

👉 試用する


✏️ routing


Next.jsはサーバ側なので、簡単にポーリングできます.
jsまたはjsxファイルを生成する場合は、ファイル名をエンドポイントとするアプリケーションでファイルにアクセスできます.

index.jsファイルはホームページなので、indexを端点とするのではなく、/でアクセスしたときのページです.

✏️ Link

<Link>を用いてページの変換を実現することができる.<Link>のherf属性を用いて、他のページへのリンクを形成することができる.
index.js 👇
import React from "react"
import Link from "next/link"

export default function Home() {
  return (
    <>
    <div>hello, world</div>
    <Link href="/hello">go to hello page</Link>
    </>
  )
}
hello.js 👇
import React from "react";
import Link from "next/link";

const HelloPage = () => {
    return(
        <React.Fragment>
            <div>this is hello page</div>
        </React.Fragment>
    );
};

export default HelloPage;
変換するページのendpointは、移動するページを表示するファイル名で作成できます.
index.jsが返す値の一番上のラベルは<>で、このラベルはhelloです.jsのReact.Fragmentと同じラベルです.

▼▼▼path変数を使う


path変数によってアクセスされるページは、[path variable 이름].js(または[path variable 이름].jsx)を生成することができる.
index.js 👇
import React, { useState } from "react"
import Link from "next/link"

export default function Home() {
  const [id, setId] = useState("input");

  return (
    <>
    <div>hello, world</div>
    <Link href="/hello">go to hello page</Link><br/>
    <input type="text" onChange={(e) => setId(e.target.value)}/>
    <Link href={`/${id}`}>
      <button>go to {id} page</button>
    </Link>
    </>
  )
}
[id].jsx 👇
import Link from "next/link";
import React, { useState } from "react";

export default function indexId(){
    return (
        <>
            <div>this is id page</div>
            <Link href={("/")}>back to index page</Link>
        </>
    );
};

移動するページでpath変数の値を使用する場合は、移動するページでuserouterというhookを使用できます.
userrouterで受信したrouterオブジェクトの値は、ページのサブページにも使用できます.
(ex./idからrouter/id/detailを受信しても使用可能)
[id].jsx 👇
import Link from "next/link";
import { useRouter } from "next/router";
import React, { useState } from "react";

export default function indexId(){
    const router = useRouter();
  // router 객체의 query에서 id라는 값을 indexId로 받아오겠다
    const {id: indexId} = router.query;

    return (
        <>
            <div>{indexId}</div>
            <Link href={("/")}>back to index page</Link>
        </>
    );
};

routerオブジェクトの値をlogに印刷すると、次のような形が表示されます.

Axiosを使用したAPI


axiosはhttpクライアントライブラリであり、外部APIを使用してデータを受信するために使用されます.
すべてのCRUDを実行し、axiosをインポートしてaxios.실행할 CRUDを使用すればよい.
import React, { useEffect, useState } from "react";
import axios from "axios";
import Link from "next/link";

const TodoPage = () => {
    // todo list를 받아서 todos에 저장
    const [todos, setTodos] = useState([])
    // await는 반드시 async 함수에서 사용
    // axios를 이용해서 값을 받아오는 부분
    useEffect( async () => {
        const resp = await axios.get("https://jsonplaceholder.typicode.com/todos");
        setTodos(resp.data);
    }, []);
    return (
        <>
            <h1>Todos</h1>
            {todos.map((todo) => (
                <div>
                    <h3>
                        <Link href={`/todos/${todo.id}`}>
                            <a>
                                <small>#{todo.id} </small> {todo.title}
                            </a>
                        </Link>
                    </h3>
                    <p>userId: {todo.userId}</p>
                    <p>{todo.completed ? "completed" : "not completed yet"}</p>
                </div>
            ))}
        </>
    );
};

export default TodoPage;

内部apiの使用


next.jsで生成されたアプリケーションはサーバ側でレンダリングされるため、内部apiを使用できます.
内部apiとして使用するコンテンツをapiディレクトリに書き込むとよい.(必須ではないようです)
pages/api/todos.js 👇
import axios from "axios";

export default async (req, res) => {
    const resp = await axios.get("https://jsonplaceholder.typicode.com/todos");
    res.status(200).json(resp.data);
};
pages/todos/index.jsx 👇
...// 위의 index.jsx의 코드와 동일한데 axios로 요청하는 api의 주소만 변경됨
 useEffect( async () => {
        const resp = await axios.get("/api/todos");
        setTodos(resp.data);
    },[]);
...
要求されたapiアドレスを内部アドレスに変更しても同様の実行結果が得られる.