0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React(Next.js + Tailwind CSS )の構成 でアプリを作成しました【Build a Pokedex】

Last updated at Posted at 2022-06-13

環境の準備

①ターミナルで、アプリケーションを作成する。

$ npx create-next-app@latest
$ cd <プロジェクト名>
$ yarn dev

② 必要なパッケージをインストールする。

公式サイト:Tailwind CSS

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

③ 不要なファイルを削除する。

api
styles/home.module.css

コンポーネント・ファイル構成

├── components
|    └── Layout.js
├── pages
|   ├── pokemon
|    |     └── [id].js
|    ├── _app.js
|    └── index.js
├── package-lock.json
├── package.json
├── postcss.config.js
└── twilwind.config.js

公式サイト:PokeAPI

components/Layout.js
import Head from 'next/head';

const Layout = ({ title, children }) => {
  return (
    <div className='bg-gray-100'>
      <Head>
        <title>{title}</title>
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <main className='container mx-auto max-w-3xl pt-8 min-h-screen'>
        {children}
      </main>
    </div>
  );
};

export default Layout;
pages/pokemon/[id].js
import Layout from '../../components/Layout';
import Link from 'next/link';

const Pokemon = ({ pokemon }) => {
  const zeroPadding = (num, len) => {
    // 指定した数値の前に指定した桁数分0を追加したあと、後ろから0桁を返す
    return (Array(len).join('0') + num).slice(-len);
  };
  return (
    <Layout title={pokemon.name}>
      <div className='m-auto w-2/3'>
        <div className='flex flex-col  bg-white rounded-md p-8 aspect-square justify-center shadow-lg'>
          <span className='ml-2 font-light'>
            No.{zeroPadding(pokemon.id + 1, 3)}
          </span>

          <img className='mx-auto' src={pokemon.image} alt={pokemon.name} />

          <h2 className='text-2xl mt-6 mb-2 font-bold'>{pokemon.name}</h2>
          {pokemon.types.map((type, index) => (
            <p key={index}>{type.type.name}</p>
          ))}
        </div>
      </div>

      <p className='mt-10 text-center'>
        <Link href='/'>
          <a>
            <button className='focus:outline-none text-white text-sm py-2.5 px-5 rounded-md bg-blue-500 hover:bg-blue-700 hover:shadow-lg'>
              一覧に戻る
            </button>
          </a>
        </Link>
      </p>
    </Layout>
  );
};

//getServerSidePropsを利用してデータを取得しページに表示させる
export const getServerSideProps = async (context) => {
  const { id } = context.query;
  const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
  const pokemon = await res.json();
  const paddedId = ('00' + id).slice(-3);
  pokemon.image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
  return {
    props: { pokemon },
  };
};

export default Pokemon;
pages/index.js
import Layout from '../components/Layout';
import Link from 'next/link';

export default function Home({ pokemon }) {
  /**
   * 足りない桁数を0埋めする関数
   * @param num: 表示させたい数値
   * @param len: 表示させたい桁数
   * @returns {string}
   */
  const zeroPadding = (num, len) => {
    // 指定した数値の前に指定した桁数分0を追加したあと、後ろから0桁を返す
    return (Array(len).join('0') + num).slice(-len);
  };
  return (
    <Layout title='NextJS PokeDex'>
      {/*  //grid-cols-{n}ユーティリティを使用して、n個の同じサイズの列を持つグリッドを作成 */}
      <div className={'grid grid-cols-3 gap-3'}>
        {pokemon.map((item, index) => (
          <p key={index}>
            <Link href={`/pokemon/${index + 1}`}>
              <a className='border-b-4 py-4 border-grey my-0 hover:shadow-md capitalize flex items-center text-xl font-bold bg-gray-100 shadow-lg'>
                <span className='mr-2 font-light'>
                  {zeroPadding(index + 1, 3)}
                </span>
                <img
                  src={item.image}
                  alt={item.name}
                  className='w-10 h-10 mr-2 font-bold'
                />
                {item.name}
              </a>
            </Link>
          </p>
        ))}
      </div>
    </Layout>
  );
}
//getServerSidePropsを利用してデータを取得しページに表示させる
export const getStaticProps = async () => {
  const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=150');
  const { results } = await res.json();
  const pokemon = results.map((pokeman, index) => {
    const paddedId = ('00' + (index + 1)).slice(-3);
    const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
    return { ...pokeman, image };
  });
  return {
    props: { pokemon },
  };
};        
styles/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
tailwind.config.js
module.exports = {
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};

参考サイト

Build a Pokedex with NextJS and Tailwind CSS
Crea una pokedex con React, NextJS y Apollo GraphQL

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?