React 基礎(chǔ)案例 | 支持左右按鈕點擊查看信息的卡片組件(二)

一、開篇
大家好,本篇文章小編將和大家一起實現(xiàn)一個用左右點擊的方式翻看卡片信息的組件,這個組件很常用,一般會在網(wǎng)站上顯示案例或團隊成員的信息。通過本案例我們繼續(xù)練習 useState Hook 在實際案例場景中的應(yīng)用。
二、案例展示
如下視頻所示,一個展示個人信息的卡片,我們可以點擊卡片下方的左右按鈕進行切換卡片的信息,用戶的信息循環(huán)展示(信息數(shù)組的兩端頭尾連接循環(huán)),同時加了一個隨機顯示的按鈕,點擊按鈕隨機顯示用戶的信息。
三、創(chuàng)建項目
開始之前,我們通過 create-react-app 命令創(chuàng)建項目文件夾 reviews,接下來刪除一些不相關(guān)的文件,保留 App.js、index.css、index.js,index.js 文件內(nèi)容如下:
import React from 'react';
import Review from './Review';
function App() {
return (
<main>
<section className="container">
<div className="title">
<h2>our reviews</h2>
<div className='underline'></div>
</div>
<Review/>
</section>
</main>
);
}
export default App;
//src/app.js
從上述代碼你可以看出我們引入了 Review 卡片組件,也是本案例的核心,稍后我會介紹到。
四、設(shè)計本地數(shù)據(jù)結(jié)構(gòu)
展示信息,需要有相關(guān)的數(shù)據(jù),本案例將用本地文件數(shù)據(jù)。本地的數(shù)據(jù)結(jié)構(gòu)比較簡單,一個數(shù)組對象,包含 id、name(姓名)、job(崗位)、image(頭像)、text(介紹),接下來我們新建一個 data.js 的文件,定義 reviews 對象變量,代碼示例如下:
const reviews = [
{
id: 1,
name: 'susan smith',
job: 'web developer',
image:
'https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883334/person-1_rfzshl.jpg',
text:
"I'm baby meggings twee health goth +1. Bicycle rights tumeric chartreuse before they sold out chambray pop-up. Shaman humblebrag pickled coloring book salvia hoodie, cold-pressed four dollar toast everyday carry",
},
...
];
export default reviews;
// src/data.js
五、完善CSS文件
基于頁面,我們新建 index.css 文件,定義卡片的展示樣式,示例代碼如下,由于代碼比較簡單,這里就不過多解釋了,這里只展示卡片的基礎(chǔ)樣式,完整代碼,請查看文末獲取方式。
/*
===============
Variables
===============
* 省略/
....
/*
===============
Reviews
===============
*/
main {
min-height: 100vh;
display: grid;
place-items: center;
}
.title {
text-align: center;
margin-bottom: 4rem;
}
.underline {
height: 0.25rem;
width: 5rem;
background: var(--clr-primary-5);
margin-left: auto;
margin-right: auto;
}
.container {
width: 80vw;
max-width: var(--fixed-width);
}
.review {
background: var(--clr-white);
padding: 1.5rem 2rem;
border-radius: var(--radius);
box-shadow: var(--light-shadow);
transition: var(--transition);
text-align: center;
}
.review:hover {
box-shadow: var(--dark-shadow);
}
.img-container {
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
margin: 0 auto;
margin-bottom: 1.5rem;
}
.person-img {
width: 100%;
display: block;
height: 100%;
object-fit: cover;
border-radius: 50%;
position: relative;
}
.quote-icon {
position: absolute;
top: 0;
left: 0;
width: 2.5rem;
height: 2.5rem;
display: grid;
place-items: center;
border-radius: 50%;
transform: translateY(25%);
background: var(--clr-primary-5);
color: var(--clr-white);
}
.img-container::before {
content: '';
width: 100%;
height: 100%;
background: var(--clr-primary-5);
position: absolute;
top: -0.25rem;
right: -0.5rem;
border-radius: 50%;
}
.author {
margin-bottom: 0.25rem;
}
.job {
margin-bottom: 0.5rem;
text-transform: uppercase;
color: var(--clr-primary-5);
font-size: 0.85rem;
}
.info {
margin-bottom: 0.75rem;
}
.prev-btn,
.next-btn {
color: var(--clr-primary-7);
font-size: 1.25rem;
background: transparent;
border-color: transparent;
margin: 0 0.5rem;
transition: var(--transition);
cursor: pointer;
}
.prev-btn:hover,
.next-btn:hover {
color: var(--clr-primary-5);
}
.random-btn {
margin-top: 0.5rem;
background: var(--clr-primary-10);
color: var(--clr-primary-5);
padding: 0.25rem 0.5rem;
text-transform: capitalize;
border-radius: var(--radius);
transition: var(--transition);
border-color: transparent;
cursor: pointer;
}
.random-btn:hover {
background: var(--clr-primary-5);
color: var(--clr-primary-1);
}
/*
src/index.css
*/
六、設(shè)計 Review 組件
接下來我們來完成本案例的核心 Review 組件,新建 Review.js 文件,用來展示卡片信息,設(shè)計思路如下:
引入 react-icons 組件,方便我們引入各種圖標,比如本案例的左右箭頭按鈕,安裝命令如下 npm install react-icons --save引入我們剛才定義的用戶數(shù)據(jù), import people from './data';定義索引狀態(tài) index,用于標識當前卡片顯示哪個用戶信息,初始默認為數(shù)組對象的第一個, const [index,setIndex]=useState(0);接著分別定義用戶信息狀態(tài)的相關(guān)變量,用于展示用戶的姓名、崗位、頭像、介紹, const {name,job,image,text}=people[index];我們繼續(xù)定義按鈕相關(guān)的事件,nextPerson(下一個),prevPerson(上一個),用于改變當前用戶的索引狀態(tài),所以加1或減1 為了讓用戶卡片信息循環(huán)顯示,比如觸發(fā) prevPerson 事件時,索引狀態(tài)為負值時,讓索引的狀態(tài)為數(shù)組索引的最后一項;同樣觸發(fā) nextPerson 事件時 ,索引狀態(tài)大于數(shù)組的長度時,需要更改為數(shù)組索引的第一項,這里我們定義 checkNumber 方法用于判斷索引的狀態(tài),更改索引狀態(tài)的值 最后我們來定義 randomPerson 事件,用于隨機顯示用戶的信息,這里需要注意處理如果隨機的索引恰好等于當前用戶的索引,避免用戶誤以為程序點了沒反應(yīng),我們需要通過索引+1的方式進行更改。
思路就聊到這里,完整的代碼如下所示:
import React, { useState } from 'react';
import people from './data';
import { FaChevronLeft, FaChevronRight, FaQuoteRight } from 'react-icons/fa';
const Review = () => {
const [index,setIndex]=useState(0);
const {name,job,image,text}=people[index];
const checkNumber = (number)=>{
if(number>people.length-1){
return 0;
}
if(number<0){
return people.length-1;
}
return number;
};
const nextPerson = ()=>{
setIndex((index)=>{
let newIndex= index + 1;
return checkNumber(newIndex);
});
};
const prevPerson =()=>{
setIndex((index)=>{
let newIndex=index-1;
return checkNumber(newIndex);
});
};
const randomPerson=()=>{
let randomNumber=Math.floor(Math.random()*people.length);
if(randomNumber===index){
randomNumber=index+1;
}
setIndex(checkNumber(randomNumber));
};
return (
<article className='review'>
<div className='img-container'>
<img src={image} alt={name} className='person-img'/>
<span className='quote-icon'>
< FaQuoteRight/>
</span>
</div>
<h4 className='author'>{name}</h4>
<p className='job'>{job}</p>
<p className='info'>{text}</p>
<div className='button-container'>
<button className='prev-btn' onClick={prevPerson}>
<FaChevronLeft/>
</button>
<button className='next-btn' onClick={nextPerson}>
<FaChevronRight/>
</button>
</div>
<button className="random-btn" onClick={randomPerson}>
surprise me
</button>
</article>
);
};
export default Review;
// src/Review.js
七、結(jié)束語
到這里,本案例就完成了,是不是很簡單,點擊卡片切換信息的比較常見,建議大家親自動手練習下,大家可以點擊閱讀原文,在線體驗,如果你想獲取本案例源碼,請關(guān)注“前端達人”公眾號,回復“b2”。感謝你的閱讀。
八、相關(guān)閱讀
React 基礎(chǔ)案例 | 提醒列表和旅游清單列表(一)
