ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [인사정보] 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;
    }}

     

    // 카드 컨테이너
    <div
    style={{
    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 입력한다. 

    <section
    key={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);
     
     
    const handleClick = (i: number) => {
    setCurrent(i);
    };
     
    <section
    key={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);
    };
    }, []);

Designed by Tistory.