#03 리액트를 사용한 팬레터 웹사이트 개발 : DummyData로 리스트 UI 구현 및 클릭한 사람 데이터만 보이기

728x90
반응형

▼ #02 리액트를 사용한 팬레터 웹사이트 개발
: 홈 화면 UI 구현 및 조건부 스타일링 (styled-component)
 
 

 

 

#02 리액트를 사용한 팬레터 웹사이트 개발 : 홈 화면 UI 구현 및 조건부 스타일링 (styled-component)

▼ #01 리액트를 사용한 팬레터 웹사이트 개발 : 라우터 설정 및 전역스타일링 설정 ▼ #01 리액트를 사용한 팬레터 웹사이트 개발 : 라우터 설정 및 전역스타일링 설정 개인프로젝트 (리액트 팬레

zerotonine2da.tistory.com


개인프로젝트 (리액트 팬레터 홈페이지 만들기 ) 과제 해설

  1. 홈 화면 UI: Dummy Data(fakeData.json)를 이용한 리스트 UI 구현 + 멤버별 팬레터 출력


(1) Dummy Data(fakeData.json)

[
    {
        "createdAt": "2023-11-03T02:07:09.423Z",
        "nickname": "Dr. Clint Christiansen",
        "content": "민지1 Vitae recusandae tenetur debitis impedit ut dolorem atque reprehenderit magnam. Cum dolor magnam commodi qui perferendis. Vel temporibus soluta. Eum delectus blanditiis. Neque dicta non quod ex. Maiores aspernatur fuga reprehenderit a magni eaque fuga voluptatum hic.",
        "writedTo": "민지",
        "id": "1"
    },
 ]

▶src 폴더 안에 'faksData.json' 생성

▶fakeData를 json파일인 이유 : 별도 export를 하지 않아도 import가 가능!

 

(2)  리스트 UI 구현

[Home.jsx]

import AddForm from 'components/AddForm';
import Header from 'components/Header';
import LetterList from 'components/LetterList';
import React from 'react';
import styled from 'styled-components';
import { useState } from 'react';

export default function Home() {
    const [activeMember, setActiveMember] = useState('민지');

    return (
        <Container>
            <Header activeMember={activeMember} setActiveMember={setActiveMember} />
            <AddForm />
            <LetterList activeMember={activeMember} />
        </Container>
    );
}

▶ Home.jsx > LetterList.jsx > LetterCard.jsx 구성

 

[LetterList.jsx]

import React from 'react';
import fakeData from 'fakeData.json';
import LetterCard from './LetterCard';
import styled from 'styled-components';

export default function LetterList({ activeMember }) {
    const filteredLetters = fakeData.filter((letter) => letter.writedTo === activeMember);

    return (
        <ListWrapper>
            {filteredLetters.map((letter) => (
                <LetterCard letter={letter} />
            ))}
        </ListWrapper>
    );
}

const ListWrapper = styled.ul`
    background-color: #8dd2ef;
    display: flex;
    flex-direction: column; /* 방향 : 세로*/
    gap: 20px;
    width: 500px;
    border-radius: 12px;
    padding: 12px;
`;

▶ filteredLetters : 멤버에게 작성된 항목만 보이도록 설정

클릭된 멤버 = activeMember (Home.jsx에서 props로 전달받아서 사용함)

▶ <ListWrapper>로 감싸주고 그 안에 <LetterCard> 컴포넌트를 구성

 

[LetterCard.jsx]

import React from 'react';
import styled from 'styled-components';
import defaultUser from 'assets/person.png';

export default function LetterCard({ letter }) {
    const formattedDate = new Date(letter.createdAt).toLocaleDateString('ko', {
        year: '2-digit',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
    });

    return (
        <LetterWrapper>
            <UserInfo>
                <AvatarFigure>
                    <img src={letter.avatar ?? defaultUser} alt="아바타이미지" />
                </AvatarFigure>
                <NickNameAndData>
                    <p>{letter.nickname}</p>
                    <time>{formattedDate}</time>
                </NickNameAndData>
            </UserInfo>
            <Content>{letter.content}</Content>
        </LetterWrapper>
    );
}

const LetterWrapper = styled.li`
    background-color: #8dd2ef;
    display: flex;
    flex-direction: column;
    gap: 12px;
    color: white;
    padding: 12px;
    border: 1px solid white;
    border-radius: 12px;
    cursor: pointer;
    &:hover {
        transform: scale(1.02);
        transition: all 0.2s; /**0.2초만에 작동 */
    }
`;
const UserInfo = styled.div`
    display: flex;
    gap: 12px;
    align-items: center; /*세로 가운데정렬 */
`;

const AvatarFigure = styled.figure`
    width: 50px;
    height: 50px;
    border-radius: 50%; /*동그라미 */
    overflow: hidden; /*이미지가 삐져나오면 안보이게 */
    & img {
        width: 100%;
        height: 100%;
        object-fit: cover; /*figure크기만큼 꽉 차게 */
        border-radius: 50%;
    }
`;

const NickNameAndData = styled.div`
    display: flex;
    flex-direction: column;
    gap: 6px;
`;

const Content = styled.p`
    background-color: gray;
    border-radius: 12px;
    padding: 12px;
    margin-left: 60px;
    white-space: nowrap; /*줄바꿈을 담당함: 줄바꿈 안함 */
    overflow: hidden; /* 초과되는 부분을 숨기기*/
    text-overflow: ellipsis; /* (생략부호=ellipsis)초과된 부분...표시 */
`;

▶ 각각의 팬레터 + 여기는 css 구간이 많음

(3) 날짜 포맷팅

    const formattedDate = new Date(letter.createdAt).toLocaleDateString('ko', {
        year: '2-digit',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
    });

▶ toLocaleDateString을 사용해서 한국시간에 맞게 2자리씩 표현 가능.

 

끝.

 


       React#04 리액트를 사용한 팬레터 웹사이트 개발  

: 팬레터 등록 기능 구현 및 유효성 검사 , 글자수 제한 방법

 

 

React#04 리액트를 사용한 팬레터 웹사이트 개발 : 팬레터 등록 기능 구현 및 유효성 검사 , 글자수

#03 리액트를 사용한 팬레터 웹사이트 개발 ▼: DummyData로 리스트 UI 구현 및 클릭한 사람 데이터만 보이기 ▼ #03 리액트를 사용한 팬레터 웹사이트 개발 : DummyData로 리스트 UI 구현 및 클릭한 사람

zerotonine2da.tistory.com


 

반응형