0
0

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.

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

Posted at

概要

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

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

RandomUser.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"
  }
}

実装のポイント

1つのユーザー欄のレイアウト-flex items-center

flex items-centerで中央揃えにしています。

image.png

SSRでユーザー情報を取得

Server Sideでランダムユーザーの情報を取得します。
image.png

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

show moreボタンを押すとユーザーの表示件数を増やす。-useStateを使う

以下Show moreボタンを押した時の様子

image.png

コード部分

Widgets

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

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

image.png

javascript

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

Next.js

React

firebase

その他

random User API

パラメーター

inc=name,login,picture

image.png

レスポンス

Postmanにて確認

image.png

Udemy

  1. Create the random users section of the widgets component

githubコミット分

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?