-
[인사정보] React url 절대 경로, url 전환, 카드 뒤집기, 로컬스토리지, 스크롤 동작React/과제 테스트 2023. 8. 9. 19:29
과제 테스트 준비
애니메이션과 로컬스토리지, 무한 스크롤 기능을 작성해봤다.
🐇 url 절대경로
모든 경로 앞에 /web/을 절대경로로 붙여주어야 합니다
1. import Router
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";2. App.tsx 파일 수정
<div><Router basename={baseUrl}><Header /> // 모든 페이지에 보임<Routes><Route path="/" element={<Home userData={userData} />} /><Route path="/signup" element={<SignUp />} /><Route path="*" element={<NotFounnd />} /></Routes></Router></div>🐇 url 전환
header의 menu를 누르면 url 바뀌어야 한다.
1. header 작성
2. react-router-dom 설치
3. Link to로 전환
// import styles from "./style/app.module.css"import styles from "../style/app.module.css";import { Link } from "react-router-dom";type RouteType = "Home" | "Signup";
const Header = () => {return (<header className={styles.header}><Link to="/"><button className={styles.headerButton}>HOME</button></Link><Link to="/signup"><button className={styles.headerButton}>SIGNUP</button></Link></header>);};
export default Header;※ useHistory
또는 useHistory 사용하는 방법도 있다.
const history = useHistory();
<button onClick={() => history.push('/new-page')}>새 페이지로 이동</button>🐇 카드 뒤집기
유저가 카드를 클릭하면 카드가 뒤집어 지고 다른 설명이 보여야 한다.
0. 먼저 카드와 컨테이너의 css를 작성해준다.
/* 카드 */.card {margin: 20px 10px;width: 100px;height: 100px;border-radius: 25px;transform-style: preserve-3d;transform-origin: center right;transition: transform 1s;box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.2);background-color: #0d0d0d;color: white;display: flex;justify-content: center;align-items: center;}}// 카드 컨테이너<divstyle={{display: "flex",flexDirection: "row",flexWrap: "wrap",justifyContent: "center",alignContent: "center",}}>1. 카드가 뒤집히는 효과를 주는 animation을 작성해준다.
🥕 애니메이션 효과
※ keyframes
@keyframes rotateBack {0% (from){transform: translateX(-100%) rotateY(-180deg);}100%(to) {transform: translateX(0) rotateY(0deg);}}
.card.is-flipped {animation: rotateBack 1s ease forwards; /* 1초 동안 rotateBack 애니메이션 실행 */}ex)
@keyframes lotate { 0% { transform : rotate(0deg) } 50% { transform : rotate(180deg) } 100% { transform : rotate(360deg) } }
2. 카드를 클릭하면 className을 바꿔주고 state로 관리한다.
const handleClick = (i: number) => {setFlipped("is-flipped");setTimeout(() => {setFlipped(""); // 1초 후에 뒤집힘 상태 초기화}, 1000);};3. card에 className 입력한다.
<sectionkey={i}className={`${styles.card} ${current === i ? styles[flipped] : ""} `}onClick={() => handleClick(i)}style={{ cursor: "pointer" }}// style={{// width: 200,// marginRight: 20,// height: 260,// backgroundColor: "#0D0D0D",// color: "white",// borderRadius: "10%",// // textAlign: "center",// // 카드 정가운데 위치// display: "flex",// justifyContent: "center",// alignItems: "center",// fontSize: 40,// fontWeight: 700,// }}>🥕 카드 정가운데에 아이템이 위치해야 한다.
display: flex;justify-content: center;align-items: center;4. 사용자가 클릭한 카드만 애니메이션이 동작하도록 id 조건을 확인한다.
const [flipped, setFlipped] = useState("");const [current, setCurrent] = useState(-1);setCurrent(i);};<sectionkey={i}className={`${styles.card} ${current === i ? styles[flipped] : ""} `} >🐇 로컬 스토리지 저장
1. 데이터는 로컬스토리지가 처음 생성될 때 로컬스토리지에 저장됩니다.
2. 브라우저 창 종료 후 재접속 했을 때, 카드의 뒤집힌 상태가 유지되도록 카드의 상태를 로컬스토리지에 기록합니다.0. http util 함수 생성한다.
import Axios from "axios";const axios = Axios.create();
export const http = {get: function get<Response = unknown>(url: string) {return axios.get<Response>(url).then((res) => res.data);},post: function post<Response = unknown, Request = any>(url: string,body?: Request) {return axios.post<Response>(url, body).then((res) => res.data);},};1. 먼저 데이터를 가져온다.
useEffect(() => {const fetchUserData = async () => {// 로컬스토리지에 데이터 있는지 확인if (localStorage.getItem("personalInfo") !== null) return;
// 로컬스토리지에 데이터 없으면 저장const personalInfo = await http.get();
console.log(personalInfo);localStorage.setItem("personalInfo", JSON.stringify(personalInfo));};
fetchUserData();}, []);2. localstorage 저장
localstorage 저장 -> stringfy
localstorage 추출 -> parse
useEffect(() => {
const setData = () => {const data = localStorage.getItem("personalInfo");if (data) setUserData(JSON.parse(data));};setData();}, []);※ JSON
JSON이란?
JavaScript Object Notation을 의미하며 경량화한 텍스트기반 데이터 교환 방식을 의미한다.
즉, 문자 기반의 데이터 포맷이다.JSON.parse()
전달받은 문자열을 자바스크립트 객체로 변환한다.
console.log(JSON.parse('{"name":"iu", "age":30}'));
// 출력 결과 {name: "iu", age: 30}
JSON.stringify()
자바스크립트 객체를 문자열로 변환한다.
매겨변수로 value, replacer, space를 받을 수 있다.
replacer와 space는 선택사항이고 value는 JSON 문자열로 반환하고 싶은 값을 넣어주면 된다.const test = { name : '아이유', age : 30 } console.log(JSON.stringify(test));
// 실행 결과 {"name":"아이유","age":30}
🥕 props로 api 데이터 전송시
※ 부모
import React from "react";import Card from "../component/Card";import { UserDataType } from "../type/type";
type HomeProps = {userData?: UserDataType[];};
const Home: React.FC<HomeProps> = ({ userData }) => {return (<div><Card userData={userData} /></div>);};
export default Home;※ 자식
type CardProps = {userData?: UserDataType[];};
type CardStatusType = {id: number;status: string;};const Card: React.FC<CardProps> = ({ userData }) => {} )🐇 무한 스크롤
페이지 하단에 도달했을 때, 그다음 카드가 순차적으로 계속 로드되는 사용자 경험을 제공하기 위해 무한스크롤 기능을 구현합니다.
동작할 함수 생성 및 이벤트 등록
// 무한 스크롤 동작const handleScroll = () => {const windowHeight = window.innerHeight;const scrollY = window.scrollY || window.pageYOffset;const bodyHeight = document.body.scrollHeight;
if (scrollY + windowHeight >= bodyHeight) {// 페이지 하단에 도달했을 때 새로운 카드 로드setVisibleCards((prevVisibleCards) => prevVisibleCards + 4);}};
useEffect(() => {window.addEventListener("scroll", handleScroll);return () => {window.removeEventListener("scroll", handleScroll);};}, []);'React > 과제 테스트' 카테고리의 다른 글
[체크리스트] 모듈화 (1) 2023.11.28 [인사정보] input,유효성 확인, dropDown, 하단창 (1) 2023.08.09 [Input 이벤트] input readonly, 백스페이스 기능 (0) 2023.08.08 [Input 이벤트] 포커스 이벤트, 영역 외부 클릭시 상태 변화, document.addEventListener (0) 2023.08.08 [고양이 사진 검색 사이트] 스크롤 페이지 구현, 랜덤 고양이 배너 section,EventDelegation (0) 2023.08.07