Next.js + Emotion (CSS in JS)で始めるReact超入門

以前、React初学者向けの勉強会を開催したときに作った資料を、Qiita向けに調整したものです。

- Reactの初歩的な記法
- Next.jsでのサーバーサイドレンダリングの概要
- CSSinJSの使い方

を学ぶことができます。

事前に[Node.js](https://nodejs.org/ja/)をインストールしている必要があります。

# Reactとは？

Reactとは、Facebookが作ったJavaScriptライブラリです。ユーザーインターフェイスをコンポーネントベースで作ることができます。

公式サイト：https://ja.reactjs.org/

## シンプルなReactのサンプル

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>

  <body>
    <div id="root"></div>

    <!-- babelがJSXをReact.createElement()に変換してくれる -->
    <script type="text/babel">
      /**
       * 引数：propsを、JSX：<div>{props.text}</div>で受け取り、returnで返す。
       * この一式をコンポーネントと呼ぶ。
       */
      function Hello(props) {
        return <div>{props.text}</div>
      };

      /**
       * Helloコンポーネントを<div id="root"></div>にマウントしている。
       * 関数みたいにしてみると、`Hello({ text: 'Hello, React!' });` こんな感じ。
       */
      ReactDOM.render(
        <Hello text="Hello, React!" />,
        document.getElementById("root")
      );
    </script>
  </body>
</html>
```

## Reactの特徴

Vue.jsがディレクティブを使いHTMLを拡張するような方法で開発するのに対し、**ReactはガシガシJavaScriptを書いていきます。**まあ、Vue.jsもガッツリ開発を始めるとガシガシJavaScriptを書くことになると思いますが（・ω・）

また、Reactは基本的に**データを受け取って適切なViewを返すこと**を目的としたシンプルなライブラリなので、Angularのようなルールはなく、**自由度がかなり高い**です。逆に言うと、しっかりとした設計ができてないと、開発途中でつらくなります（・ω・）

## 宣言的UI

Reactに限らず、近年のUIフレームワーク・ライブラリ、およびプログラミングにおいて主要なパラダイムである**宣言的UI**について、知っておく必要があります。

そのまえに、まず、**命令的と宣言的**を解説します。

### 命令的
- 何をするかを記述する
- 前回の実行結果に依存する
  - 変数の再代入が行われる

### 宣言的
- どういう状態になるのかを記述する
- 前回の実行結果に依存しない
  - 変数に再代入しない

### 命令的UIと宣言的UI

#### 命令的UI

命令的UIの例として、jQueryによるDOM操作があげられます。

```html
<!-- この時点ではUIの最終的な状態はわからない -->
<ul id="list"></ul>
```
```js
const animals = ["ねずみ", "うし", "とら"];

// 配列の要素分処理を繰り返し、HTML側に挿入することでUIが決定する。
animals.forEach(animal => {
  $('#list').append(`<li>${animal}</li>`);
});
```

#### 宣言的UI

一方で、**Vue.js**は宣言的にUIを作ることができます。

```html
<template>
  <ul>
    <!-- この時点でUIの状態が決まっている -->
    <li v-for="(item, index) in list" :key="index">{{item}}</li>
  </ul>
</template>

<script>
  export default {
    data() {
      return {
        // 配列の要素によってリストの数が決定する
        list: ["ねずみ", "うし", "とら"]
      };
    }
  };
</script>
```

ReactやVue.jsは、jQueryの次に流行っているフレームワーク・ライブラリではなく、**宣言的なUIを作るためのフレームワーク・ライブラリ**です。

技術選定時に宣言的なUIが必要であれば、ReactやVue.jsを使用しましょう。逆に言えば、jQueryのほうが適切な場面であれば、無理に使用する必要はありません。

# Next.jsとは？

**Next.js**とは、Reactでサーバーサイドレンダリングをするためのフレームワークです。Vue.jsで言うところの、Nuxt.js。簡単にルーティングできて、静的サイトの書き出しもできます。

公式サイト：https://nextjs.org/

静的サイトの書き出しならば、[Gatsby.js](https://www.gatsbyjs.org/)のほうが使いやすいかもしれませんが、Next.jsのほうがシンプルに始められるので、今回はNext.jsを使用します。

Reactとしての書き方はほぼ同じですし、メジャーなエコシステムも使用できるなので、Next.jsが使えればGatsby.jsも使えると思います。多分。

## サーバーサイドレンダリングとは？

サーバーサイドレンダリングとは、**PHP**や**Ruby**、**Java**のように、サーバーサイドでDOMを生成してクライアントに静的なHTMLとして渡すことです。

Reactは、本来クライアントサイドで仮想DOMを生成し、それを実DOMとしてブラウザに描画します。

```html
<!-- サーバーから返されるHTML -->
<div id="app"></div>
```

```jsx
import React from 'react';
import ReactDOM from "react-dom";

// クライアントサイドでDOMを書き換える
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);
```

サーバーサイドレンダリングは、サーバー上でReactを実行し、生成したDOMをクライアントへ渡します。

たとえば、動的なコンテンツで`<title>`要素や`<meta>`要素をクライアントサイドで生成すると、TwitterやFacebook等のSNSでシェアしたときには反映されません。

しかし、サーバーサイド上で事前にDOMを生成すれば、クライアントからみれば静的なHTMLがレスポンスとして返ってくるので、この問題が回避できます。

## Next.jsの使い方

必要なパッケージをインストール

- next
- react
- react-dom

```console
$ mkdir nextjs-sample
$ cd nextjs-sample
$ npm init -y
$ npm i next react react-dom
```

`package.json`に`scripts`を追記。

```json
{
  "scripts": {
    "dev": "next"
  }
}
```

`./pages`ディレクトリに`index.js`を追加。

```console
$ mkdir pages
$ touch pages/index.js
```

```jsx
// pages/index.js
export default () => <h1>Hello, Next.js!</h1>
```

ローカルサーバーを起動。

```console
$ npm run dev
```

`http://localhost:3000`にアクセスして、`Hello, Next.js!`が表示されていれば、OK！

## ディレクトリ構成

- `./pages` ルーティングの対象
- `./static` 静的ファイルの置き場所
  - 画像ファイルとか

ディレクトリのルールが決まっているのは、これくらい。

また、**Next.js 9.1**から`src`配下でも利用できるようになったので、以下でもOKです。

- `src/pages` ルーティングの対象
- `src/static` 静的ファイルの置き場所

## JSX

JSXを使用すると、JavaScript上でHTMLのような構文が使えます。

```jsx
// JSX
const Button = <button className="my-button">ボタン</button>
```

これは、`React.createElement()`の糖衣構文で、JSXを使わないと下記の記述になります。

```jsx
const Button = React.createElement("button", {
  className: "my-button"
}, "ボタン");
```

極論、JSXを使わずに`React.createElement()`を使ってもなんの問題ありません。

[JSXを使う理由](https://ja.reactjs.org/docs/introducing-jsx.html#why-jsx)が公式のガイドにありますので、興味のある方はどうぞ。

[オンライン Babel コンパイラ](https://babeljs.io/repl/#?presets=react&code_lz=GYVwdgxgLglg9mABACwKYBt1wBQEpEDeAUIogE6pQhlIA8AJjAG4B8AEhlogO5xnr0AhLQD0jVgG4iAXyJA)を使うと、JSXがどのようなJavaScriptに変換されるのかを確認できます。

## Next.js（React）を書いてみよう

`pages/index.js`を、省略形なしの形に変更。

```jsx
import React from 'react' // Next.jsでは省略可能

// returnでJSXを返す関数をコンポーネントと呼ぶ
function Index() {
  return <h1>Hello, Next.js!</h1>
}

// ES Modules
// 本来は import されて react-dom がレンダリングするが、Next.jsでは隠蔽されている
export default Index
```

HTMLのように、JSXでも子要素を使うことができます。

```jsx
import React from 'react'

function Index() {
  // ()で括り、;の自動挿入に対応
  // returnで返すJSXは必ず1つの要素
  return (
    <div>
      <h1>Hello, Next.js!</h1>
    </div>
  )
}

export default Index
```

JSXは`{}`でJavaScriptを使うことができます。

```jsx
import React from 'react'

function Index() {
  const text = 'Next.js!'
  return (
    <div>
      {/* コメントアウト */}
      <h1>{`Hello, ${text}`}</h1>
    </div>
  )
}

export default Index
```

`Heading`コンポーネントを作って、JSX内で使ってみましょう。

```jsx
import React from 'react'

// 見出し用のコンポーネント
function Heading(props) {
  // 属性の値は、オブジェクトのプロパティとして渡される
  return <h1>{props.text}</h1>
}

function Index() {
  const text = 'Next.js!'
  return (
    <div>
      {
        /**
        * コンポーネントの属性でテキストを渡す
        * これをProps（プロップス）と呼ぶ
        */
      }
      <Heading text={`Hello, ${text}`} />
    </div>
  )
}

export default Index
```

`Heading`コンポーネントに、子要素を渡してみます。

```jsx
import React from 'react'

// Propsはオブジェクトなので、分割代入が使える
function Heading({ children }) {
  // childrenで子要素を受け取る
  return <h1>{children}</h1>
}

function Index() {
  const text = 'Next.js!'

  return (
    <div>
      {/* コンポーネントの子要素でspan要素を渡す */}
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
    </div>
  )
}

export default Index
```

`div`がいらねえときは、`React.Fragment`が便利です。

```jsx
import React from 'react'

function Heading({ children }) {
  return <h1>{children}</h1>
}

function Index() {
  const text = 'Next.js!'
  // React.Fragmentを使うとその要素はレンダリングされない
  return (
    <React.Fragment>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <p>divでラップしたないねん</p>
    </React.Fragment>
  )
}

export default Index
```

`React.Fragment`は、糖衣構文として`<></>`とも使えます。記述量が遥かに少なくてすむので、とくに理由がなければ、こちらを使用しましょう。

```jsx
import React from 'react'

function Heading({ children }) {
  return <h1>{children}</h1>
}

function Index() {
  const text = 'Next.js!'
  // <React.Fragment></React.Fragment>は<></>とも書ける
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <p>divでラップしたないねん</p>
    </>
  )
}

export default Index
```

ファイルを分けてみましょう。

```console
$ mkdir components 
$ touch components/Heading.js
```

```jsx
// components/Heading.js
// {} と return を省略できる
function Heading({ children }) {
  return <h1>{children}</h1>
}

export default Heading
```

```jsx
// pages/index.js
import React from 'react'
import Heading from '../components/Heading'

function Index() {
  const text = 'Next.js!'
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <p>divでラップしたないねん</p>
    </>
  )
}

export default Index
```

`map`メソッドで要素の反復処理をしてみましょう。

```jsx
// pages/index.js
import React from 'react'
import Heading from '../components/Heading'

// 配列
const member = ['ネズミ', '牛', 'トラ', 'うさぎ']

function Index() {
  const text = 'Next.js!'
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <ul>
        {member.map((name, index) => (
          <li key={index}>{name}</li>
        ))}
      </ul>
    </>
  )
}

export default Index
```

`onClick`でイベント発火できます。

```jsx
// pages/index.js
import React from 'react'
import Heading from '../components/Heading'

const member = ['ネズミ', '牛', 'トラ', 'うさぎ']

function Index() {
  const text = 'Next.js!'
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <ul>
        {member.map((name, index) => (
          <li key={index}>{name}</li>
        ))}
      </ul>

      {/* onClickに関数を書く */}
      <button onClick={() => console.log('onClick')}>ボタン</button>
    </>
  )
}

export default Index
```

### useStateで関数コンポーネントに状態をもたせる

React 16.8で、[hooks](https://ja.reactjs.org/docs/hooks-intro.html)という新機能が追加されました。Reactで`state`などの機能を使う場合、これまではクラスで書かないといけませんでしたが、hooksの登場で関数コンポーネントでも副作用のある機能を使うことができるようになりました。

今回は、関数コンポーネントに状態をもたせることができる、`useState`を使ってみましょう。

```jsx
// pages/index.js
// `useState`をインポート
import React, { useState } from 'react'
import Heading from '../components/Heading'

const member = ['ネズミ', '牛', 'トラ', 'うさぎ']

function Index() {
  const text = 'Next.js!'
  
  /**
 * const [変数, 変数の値を変える関数] = useState(初期値)
 * 以下では、`value`変数の初期値に`No, Click.`の文字列を代入しています。
 * setValue('Yes, Click!!')を実行すると、
 * valueの値を`No, Click.`から`Yes, Click!!`に変えることができます。
 */
  const [value, setValue] = useState('No, Click.');
  const onClickEvent = () => setValue('Yes, Click!!');

  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <ul>
        {member.map((name, index) => (
          <li key={index}>{name}</li>
        ))}
      </ul>
      <button onClick={() => console.log('onClick')}>ボタン</button>

      {/* クリックすると、`No, Click.`が`Yes, Click!!`に変わる */}
      <button onClick={onClickEvent}>{value}</button>
    </>
  )
}

export default Index
```

### Next.js独自の機能

`Link`コンポーネントでルーティングさせてみましょう。

```jsx
// pages/index.js
import React, { useState } from 'react'
import Link from 'next/link' // Linkコンポーネントを追加
import Heading from '../components/Heading'

const member = ['ネズミ', '牛', 'トラ', 'うさぎ']

function Index() {
  const text = 'Next.js!'
  const [value, setValue] = useState('No, Click.');
  const onClickEvent = () => setValue('Yes, Click!!');
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <ul>
        {member.map((name, index) => (
          <li key={index}>{name}</li>
        ))}
      </ul>
      <button onClick={() => console.log('onClick')}>ボタン</button>
      <button onClick={onClickEvent}>{value}</button>

      {/* Linkコンポーネントでルーティングできる */}
      <Link href="/batman"><a>バットマンページへ</a></Link>
    </>
  )
}

export default Index
```

`pages/batman.js`を作成した上、**バットマンページへ**のリンクをクリックすると、再読み込みなしでページ遷移できます。つまり、SPAです。

```console
$ touch pages/batman.js
```

```jsx
// pages/batman.js
import React from 'react'

function Batman() {
  return <div>batman</div>
}

export default Batman
```

### `getInitialProps`で非同期データ取得

`getInitialProps`は、Next.jsのライフサイクルメソッドです。ページが読み込まれたときはサーバーサイドで実行され、以降、`Link`コンポーネントによって別の`pages`コンポーネントへ移動した場合にクライアントサイドで実行されます。

以下の実装をして、`http://localhost:3000`から`http://localhost:3000/batman`に遷移したときと、`http://localhost:3000/batman`をリロードしたときのコンソールの表示を確認してみましょう。

```jsx
// pages/batman.js
import React from 'react'

function Batman({ text }) {
  return <div>{text}</div>
}

Batman.getInitialProps = () => {
  const text = 'I am Batman !!'
  return { text } // returnしたオブジェクトをコンポーネントのPropsとして受け取れます
}

export default Batman

```

遷移したときはブラウザ側のコンソール、リロードしたときは開発側のコンソールに、それぞれログが出たかと思います。

Next.jsはサーバーサイドレンダリングのためのフレームワークなので、今書いているJavaScriptが**サーバーサイド（Node.js）なのか？**それとも、**クライアントサイドなのか？**を意識することが必要です。

#### 非同期でデータ取得

バットマンAPIを叩いて、非同期に情報を取得してみましょう。ページ読み込み時になにかしらの処理をする場合は、`getInitialProps`メソッドを使います。

Node.jsではfetchメソッドが使えないので、`isomorphic-unfetch`をインストールして使います。

```
$ npm i isomorphic-unfetch
```

```jsx
// pages/batman.js
import React from 'react'
import fetch from 'isomorphic-unfetch'

function Batman({ shows }) {
  return (
    <div>
      <h1>Batman TV Shows</h1>
      <ul>
        {shows.map(show => (
          <li key={show.id}>
            <div><img src={show.image.medium} /></div>
            <div>{show.name}</div>
          </li>
        ))}
      </ul>
    </div>
  )
}

Batman.getInitialProps = async () => {
  const res = await fetch('https://api.tvmaze.com/search/shows?q=batman')
  const data = await res.json();
  return {
    shows: data.map(entry => entry.show)
  }
}

export default Batman
```

## サーバーサイドレンダリングの使い所

> たとえば、動的なコンテンツで`<title>`要素や`<meta>`要素をクライアントサイドで生成すると、TwitterやFacebook等のSNSでシェアしたときには反映されません。
> 
> しかし、サーバーサイド上で事前にDOMを生成すれば、クライアントからみれば静的なHTMLがレスポンスとして返ってくるので、この問題が回避できます。

クソアプリを作ったので、これを実際に試してみましょう。

```console
$ touch pages/nameApp.js
$ touch pages/yourName.js
```

```jsx
// nameApp.js
import React, { useState } from 'react'
import { useRouter } from 'next/router'

function NameApp() {
  const [name, setValue] = useState('')

  /**
   * Next.jsのルーターオブジェクト
   * https://nextjs.org/docs#userouter
   */
  const router = useRouter()

  const onClickEvent = () => {
    // yourname?name=【name】に遷移する
    router.push({
      pathname: '/yourName',
      query: { name },
    })
  }

  const onChangeEvent = event => setValue(event.target.value)

  return (
    <>
      <div>君の名は。。。</div>
      <input value={name} onChange={onChangeEvent} />
      <button onClick={onClickEvent}>click!!</button>
    </>
  )
}

export default NameApp
```

`nameApp.js`のやっていることは、ReactやNext.jsを使わない方法で書くとこんな感じです。

```html
<form action="yourName/" method="GET">
  <div>君の名は。。。</div>
  <input name="name"/>
  <button type="submit">click!!</button>
</form>
```

続いて、遷移先の`yourName.js`を実装します。

```jsx
// yourName
import React from 'react'
import Head from 'next/head'

function YourName({ query }) {
  const { name } = query
  return (
    <>
      {/* Headコンポーネントで`title`や`meta`が設定できる */}
      <Head>
        <title>{name} | YourName</title>
        <meta name="description" content={`君の名は、${name}ですね。`} />
      </Head>
      <div>
        君の名は、<strong>{name}</strong>ですね。
      </div>
    </>
  )
}

YourName.getInitialProps = ({ query }) => {
  return { query }
}

export default YourName
```

フォームに名前を入力して隣のボタンをクリックすると、入力した名前を表示することができる画期的なアプリです。

`command + option + u`でソースを確認してみましょう。サーバーから取得したHTMLの段階で、`title`や`meta`が設定されていることがわかります。

イメージを掴んでいただくために、試しに**PHP**で実装してみました。（PHPが全然わからないので細かいところはご勘弁を。。。(´；ω；｀)）

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>YourName</title>
</head>
<body>
  <form action="yourName/" method="GET">
    <div>君の名は。。。</div>
    <input name="name"/>
    <button type="submit">click!!</button>
  </form>
</body>
</html>
```

上のHTMLで`yourName/?name=ほげぼげ`みたいな感じになるので、PHPでパラメーターを受け取りHTMLとしてクライアントにレスポンスします。

```html
<!-- yourName/index.php -->
<?php $name = htmlspecialchars($_GET['name']); ?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title><?php echo $name; ?> | YourName</title>
  <meta name="description" content="君の名は、<?php echo $name; ?>ですね。" />
</head>
<body>
  <div>君の名は、<?php echo $name; ?>ですね。</div>
</body>
</html>
```

より掘り下げたい場合は、[公式ドキュメント](https://nextjs.org/docs)を確認してください。

また、GitHubの[example](https://github.com/zeit/next.js/tree/canary/examples)に豊富なサンプルがあるので、とても参考になります。

# EmotionでCSS in JS

**Emotion**とは、JavaScriptでCSSスタイルを記述するために設計されたライブラリです。後発ライブラリのため、**styled-component**等の良いとこ取りをしています。

必要なパッケージをインストールしましょ。

- @emotion/styled
- @emotion/core

```console
$ npm i @emotion/styled @emotion/core
```

## Emotionを使ってみよう

**@emotion/styled**を使い、styled-componentライクなコンポーネントを作ってみます。

```jsx
// components/Heading.js
// @emotion/styledをインポート
import styled from '@emotion/styled'

// styled.{要素}`{css}` の形で使用します。
// 定数に代入することで、コンポーネントとして利用できます。
// ブラウザ上ではユニークな文字列のCSSクラスが付与されるので、CSSはスコープになります。
const HeadingStyle = styled.h1`
  font-size: 20px;
  color: red;
`

function Heading({ children }) {
  return <HeadingStyle>{children}</HeadingStyle>
}

export default Heading
```

CSS部分はテンプレートリテラルなので、`${}`内でJavaScriptが利用できます。

```jsx
// components/Heading.js
import styled from '@emotion/styled'

// フォントサイズを定数化
const fontSize = 20

// テンプレートリテラル内で定数を使用
const HeadingStyle = styled.h1`
  font-size: ${fontSize}px;
  color: red;
`

function Heading({ children }) {
  return <HeadingStyle>{children}</HeadingStyle>
}

export default Heading
```

コンポーネント側からProps経由で値を渡すことができます。別ファイルにしてデータを渡してみましょう。

```console
$ touch components/HeadingStyle.js
```

```jsx
// components/HeadingStyle.js
import styled from '@emotion/styled'

// ES Modules
// 関数の引数としてデータを受け取ります
export const HeadingStyle = styled.h1`
  font-size: ${props => props.fontSize}px;
  color: red;
`
```

```jsx
// components/Heading.js
import { HeadingStyle } from './HeadingStyle'

const fontSize = 20

function Heading({ children }) {
  return <HeadingStyle fontSize={fontSize} >{children}</HeadingStyle>
}

export default Heading
```

**SCSS**のようにネストが使えます。

```js
// components/HeadingStyle.js
import styled from '@emotion/styled'

// SCSSのように&が使えます。
export const HeadingStyle = styled.h1`
  font-size: ${props => props.fontSize}px;
  color: red;
  
  &:hover {
    color: green;
  }
`
```

## CSS in JSのメリット

たとえば、ブレークポイントをJavaScriptで管理すれば、Carouselのライブラリ等と共通の値を使うことができます。

```console
$ mkdir const
$ touch const/breakPoints.js
```

```js
// const/breakPoints.js
const breakPoints = {
  xs: 0,
  sm: 576,
  md: 768,
  lg: 992,
  xl: 1200
}

export default breakPoints
```

```js
// components/HeadingStyle.js
import styled from '@emotion/styled'
import breakPoints from '../const/breakPoints'

export const HeadingStyle = styled.h1`
  font-size: ${props => props.fontSize}px;
  color: red;
  
  @media (min-width: ${breakPoints.md}px) {
    color: green;
  }
`;
```

**react-slick**を使ってみましょ。

https://react-slick.neostack.com/

```console
$ npm i react-slick slick-carousel raw-loader
$ touch next.config.js
```

`next.config.js`で、Next.jsが隠蔽しているwebpackの設定にアクセスできます。**raw-loader**を追加して、CSSファイルを扱えるようにします。

```js
// next.config.js
module.exports = {
  webpack: config => {
    config.module.rules.push({
      test: /\.css$/,
      use: "raw-loader"
    });
    return config
  }
}

```

スライダーコンポーネントを作り、トップページで使ってみましょう。

```console
$ touch components/MySlider.js
```

```jsx
// components/MySlider.js
import React from 'react'
import styled from '@emotion/styled'
import Slider from 'react-slick'
import slickCss from 'slick-carousel/slick/slick.css'
import slickThemeCss from 'slick-carousel/slick/slick-theme.css'
import breakPoints from '../const/breakPoints'

const settings = {
  infinite: false,
  slidesToShow: 2,
  slidesToScroll: 2,
  responsive: [
    {
      breakpoint: breakPoints.md, // const/breakPoints.jsの値が使える
      settings: {
        infinite: true,
        slidesToShow: 1,
        slidesToScroll: 1,
      }
    }
  ]
};

const SliderWrapperStyle = styled.div`
  ${slickCss}
  ${slickThemeCss}
`

function MySlider({ member }) {
  return (
    <SliderWrapperStyle>
      <Slider {...settings}>
       {member.map((animal, index) => (
         <div key={index}>{animal}</div>
       ))}
      </Slider>
    </SliderWrapperStyle>
  )
}

export default MySlider
```

```jsx
// pages/index.js
import React, { useState } from 'react'
import Link from 'next/link'
import MySlider from "../components/MySlider";
import Heading from '../components/Heading'

const member = ['ネズミ', '牛', 'トラ', 'うさぎ']

function Index() {
  const text = 'Next.js!'
  const [value, setValue] = useState('No, Click.');
  const onClickEvent = () => setValue('Yes, Click!!');
  return (
    <>
      <Heading>
        <span>{`Hello, ${text}`}</span>
      </Heading>
      <button onClick={() => console.log("onClick")}>ボタン</button>
      <button onClick={onClickEvent}>{value}</button>
      <Link href="/batman">
        <a>バットマンページへ</a>
      </Link>

      {/* member配列をPropsで渡す */}
      <MySlider member={member} />
    </>
  );
}

export default Index
```

他にも**Emotion**でいろいろなことができるので、ぜひ掘り下げてみてください。

公式ガイド：https://emotion.sh/docs/introduction