Twitter clone Part7　ユーザーをランダムに表示

# 概要
今回は右側にランダムユーザーを表示する機能を実装します。

randomuser APIからランダムにユーザー情報を取得しています。
以下実装後の様子です。

![RandomUser.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/525f9fd0-1470-f7d4-ef92-b7bc01e68e6f.gif)

# 開発環境

OS:Windows10
IDE:VSCode


```package.json
{
  "name": "",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@heroicons/react": "^1.0.6",
    "next": "12.0.9",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "@types/node": "^20.4.2",
    "@types/react": "^18.2.15",
    "autoprefixer": "^10.4.2",
    "eslint": "8.8.0",
    "eslint-config-next": "12.0.9",
    "postcss": "^8.4.5",
    "tailwindcss": "^3.0.18"
  }
}
```

# 実装のポイント

## １つのユーザー欄のレイアウト-flex items-center
flex items-centerで中央揃えにしています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/ac9ebeb5-f15f-51eb-6695-0fe4116fd542.png)


## SSRでユーザー情報を取得
Server Sideでランダムユーザーの情報を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/e132899a-a853-3a92-029b-72b845bc0589.png)

SSRにする理由
実行するAPIのパスパラメータ、クエリパラメータ、リクエストボディが同じだからです。
１つのサーバー側で１回実行してレスポンスをクライアント側に渡せば、クライアント側の負担を減らすことができます。


## show moreボタンを押すとユーザーの表示件数を増やす。-useStateを使う
以下Show moreボタンを押した時の様子

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/62288e4d-7665-4706-c289-73979f9e1c8d.png)



# コード部分
## Widgets
```diff_jsx:Widgets.jsx

import { SearchIcon } from "@heroicons/react/outline";
import News from "./News";
import { useState } from "react";

- export default function Widgets({ newsResults }) {
+ export default function Widgets({ newsResults,randomUserResults }){
  const [articleNum, setArticleNum] = useState(3);
+  const [randomUserNum,setRandomUserNum] = useState(3);
  return (
    <div className="xl:w-[600px] hidden lg:inline ml-8 space-y-5">
      <div className="w-[90%] xl:w-[75%] sticky top-0 bg-white py-1.5 z-50">
        <div className="flex items-center p-3 rounded-full bg-red-300 relative">
          <SearchIcon className="h-5 z-50 text-gray-500" />
          <input
            className="absolute inset-0 rounded-full pl-11 border-gray-500 text-gray-700 focus:shadow-lg focus:bg-white bg-gray-100 "
            type="text"
            placeholder="Search Twitter"
          />
        </div>
      </div>

      <div className="text-gray-700 space-y-3 bg-gray-100 rounded-xl pt-2 w-[90%] xl:w-[75%]">
        <h4 className="font-bold text-xl px-4">What's happening</h4>
        {newsResults.slice(0, articleNum).map((article) => (
          <News key={article.title} article={article} />
        ))}
        <button onClick={()=>setArticleNum(articleNum + 3)}  className="text-blue-300 pl-4 pb-3 hover:text-blue-400">
          Show more
        </button>
      </div>
      <div className="sticky top-16 text-gray-700 space-y-3 bg-gray-100 pt-2 rounded-xl w-[90%] xl:w-[75%]" >
+        <h4 className="sticky text-xl top-16 text-gray-700 space-y-3">Who to follow</h4>
+        {randomUserResults.slice(0,randomUserNum).map((randomUser) => (
+          <div key={randomUser.login.username} className="flex items-center hover:bg-gray-200">
+            <img className="rounded-full" width="40" src={randomUser.picture.thumbnail} alt="" />
+            <div className="truncate ml-4 leading-5">
+              <h4 className="font-bold hover:underline text-[14px] truncate">
+                {randomUser.login.username}
+              </h4>
+              <h5 className="text-[-13px] text-gray-500 truncate">
+                {randomUser.name.first + "" + randomUser.name.last}
+              </h5>
+            </div>
+            <button className="ml-auto bg-black text-white rounded-full text-sm px-3.5 py-1.5 font-bold">
+              Follow
+            </button>
+          </div>
+        ))}
+        <button onClick={()=> setRandomUserNum(randomUserNum + 3)} className="text-blue-300 pl-4 pb-3 hover:text-blue-400">
+          Show more
+        </button>
+      </div>
    </div>
  );}
```

## pages/index
```diff_jsx:index.jsx
import Head from 'next/head'
import Image from 'next/image'
import Sidebar from '../components/Sidebar';
import Feed from '../components/Feed';
import Widgets from '../components/Widgets';

- export default function Home({ newsResults }) {
+ export default function Home({ newsResults, randomUserResults }) {
  return (
    <div>
      <Head>
        <title>Twitter Clone</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className="flex min-h-screen mx-auto">
        {/* Header */}

        {/* Sidebar */}
        <Sidebar />


        {/* Feed */}
        <Feed/>
        {/* Modal */}
-        <Widgets newsResults={newsResults.articles} />
+        <Widgets newsResults={newsResults.articles} randomUserResults={randomUserResults.results} />
      </main>
    </div>
  )
}


// 
export async function getServerSideProps() {
  const newsResults = await fetch(
    "https://saurav.tech/NewsAPI/top-headlines/category/business/us.json"
  ).then((res) => res.json());
  
+  const randomUserResults = await fetch(
+    "https://randomuser.me/api/?results=30&inc=name,login,picture"
+  ).then((res) => res.json());

  return {
    props: {
      newsResults,
+      randomUserResults
    },
  };
}
```





# 参考

## css
### center-item

https://tailwindcss.com/docs/align-items

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/5337ea25-cee7-7f99-51d2-7c4e9e7e10cb.png)


## javascript

### Array.prototype.slice(start,end) 配列のstart目からend目までの要素を配列として返す。　


https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

## Next.js


## React

## firebase

## その他


### random User API

https://randomuser.me/

#### パラメーター
##### inc=name,login,picture


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/9dac9ebd-0a8e-9969-0e96-e8a9f0cd3aa6.png)


##### レスポンス
Postmanにて確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/1e19fdf0-ded4-b1ef-2bb3-c1965ef7fbb7.png)


Udemy

74. Create the random users section of the widgets component

https://www.udemy.com/course/react-js-tutorial/learn/lecture/32461746?start=300#overview

githubコミット分

https://github.com/RYA234/twitter-clone/commit/339c5316b915e84848c2ea16aad8ad6d5edb80af