概要
今回は右側にランダムユーザーを表示する機能を実装します。
randomuser APIからランダムにユーザー情報を取得しています。
以下実装後の様子です。
開発環境
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で中央揃えにしています。
SSRでユーザー情報を取得
Server Sideでランダムユーザーの情報を取得します。
SSRにする理由
実行するAPIのパスパラメータ、クエリパラメータ、リクエストボディが同じだからです。
1つのサーバー側で1回実行してレスポンスをクライアント側に渡せば、クライアント側の負担を減らすことができます。
show moreボタンを押すとユーザーの表示件数を増やす。-useStateを使う
以下Show moreボタンを押した時の様子
コード部分
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
javascript
Array.prototype.slice(start,end) 配列のstart目からend目までの要素を配列として返す。
Next.js
React
firebase
その他
random User API
パラメーター
inc=name,login,picture
レスポンス
Postmanにて確認
Udemy
- Create the random users section of the widgets component
githubコミット分