22.12.15 ~ 23.06.08 코드스테이츠
[React] React Twittler Intro 과제
디디 ( DD )
2023. 1. 20. 21:18
> 상세 컴포넌트 구현하기
Sidebar 컴포넌트 기술 요구사항
- App 컴포넌트의 후손 컴포넌트로 Sidebar 컴포넌트가 있어야 합니다.
- Font Awesome을 활용하여 트윗 메시지 아이콘이 있어야 합니다. (className : "far fa-comment-dots").
const Sidebar = () => {
return (
<section className="sidebar">
<i className="far fa-comment-dots"></i> //Font Awesome을 활용하여 아이콘 구성.
</section>
);
};
→ kit를 head 태그 안에 위치시키는 선행 작업이 필요하다.
Counter 컴포넌트 기술 요구사항
- Feature 컴포넌트의 후손 컴포넌트로 Counter 컴포넌트가 있어야 합니다.
- dummyTweet로 전달되는 트윗 개수와 카운트가 일치해야 합니다. ex) total : 5
- total과 숫자가 콘텐츠에 포함되어 있어야 합니다.
const Counter = () => {
return (
<div className="tweetForm__input">
<div className="tweetForm__inputWrapper">
<div className="tweetForm__count" role="status">
{`total: ${dummyTweets.length}`} //dummyTweet이 배열 형태이므로 length를 이용.
//{'total: ' + dummyTweets.length}
</div>
</div>
</div>
);
};
Footer 컴포넌트 기술 요구사항
- Features 컴포넌트의 후손 컴포넌트로 Footer 컴포넌트가 있어야 합니다.
- Footer 컴포넌트의 후손 엘리먼트로 시맨틱 엘리먼트 footer가 있어야 합니다.
- 시멘틱 엘리먼트 <footer>가 포함되어야 합니다.
const Footer = () => {
return (
<footer>
<img id="logo" src={`${process.env.PUBLIC_URL}/codestates-logo.png`} />
Copyright @ 2022 Code States
</footer>
);
};
→ 원래 코드는 <footer>대신에 <div>가 쓰여 있었다. 그리고 나는 Copyright 부분에만 <footer>를 씌워 테스트를 통과했다. 하지만 지금 보니 요구 사항이 정확하게 원하는 것은 위 레퍼런스 코드인 것 같다. 로고 이미지도 <footer>에 포함되어 Footer 컴포넌트로 한 데 묶이는 것이 의미적으로 맞기 때문이다.
Tweets 컴포넌트 기술 요구사항
- 트윗 저자의 프로필 사진이 있어야 합니다.
- li.tweet 엘리먼트의 후손 엘리먼트로 <img> 엘리먼트를 생성하고 dummyTweets의 이미지 주소 정보를 찾아서 <src> 속성을 지정합니다.
- 유저 이름이 있어야 합니다.
- li.tweet 엘리먼트의 후손 엘리먼트로 <span> 엘리먼트를 생성하고 dummyTweets의 유저 이름을 <span>의 텍스트 콘텐츠로 넣습니다.
- 클래스 이름은 tweet__username으로 지정합니다.
- 트윗 생성 일자(yyyy. m. d.) 가 있어야 합니다.
- li.tweet 엘리먼트의 후손 엘리먼트로 <span> 엘리먼트를 생성하고 dummyTweets의 트윗 생성 일자를 <span>의 텍스트 콘텐츠로 넣습니다.
- 클래스 이름은 tweet__createdAt으로 지정합니다.
- 트윗 생성 일자는 yyyy. m. d. 형식으로 표시되어야 합니다. (’static/dummyTweets.js’ 파일을 잘 읽어보세요.)
- 트윗 메시지가 있어야 합니다.
- li.tweet 엘리먼트의 후손 엘리먼트로 <div> 엘리먼트를 생성하고 dummyTweets의 트윗 내용을 <div> 의 텍스트 콘텐츠로 넣습니다.
- 클래스 이름은 tweet__message으로 지정합니다.
- 트윗이 dummyTweets의 길이만큼 있어야 합니다.
- dummyTweets에 트윗이 n개 전달되면, 화면에 트윗이 n개가 보여야 합니다.
> 핵심 기능 구현하기
조건부 렌더링 기술 요구사항
- 조건부 렌더링을 활용해서 여러 트윗 중 유저 이름이 parkhacker인 배경색이 var(--point-color-tint-2)가 되도록 클래스(tweet__username--purple)를 지정해야 합니다. (tweet__username tweet__username--purple)
- ‘src/App.css’에 클래스가 미리 준비되어 있습니다. (className : 'tweet__username--purple')
const Tweets = () => {
return (
<ul className="tweets">
{dummyTweets.map((tweet) => {
return (
<li className="tweet" key={tweet.id}>
<div className="tweet__profile">
<img src={tweet.picture}/> //저자의 프로필 사진
</div>
<div className="tweet__content">
<div className="tweet__userInfo">
{tweet.username === 'parkhacker' //이름이 "parkhacker"인 경우,
? <span className='tweet__username tweet__username--purple'>{tweet.username}</span>
//배경색이 있는 <유저 이름 span>
: <span className='tweet__username'>{tweet.username}</span>}
//아닌 경우, 일반 <유저 이름 span>
<span className="tweet__createdAt">{tweet.createdAt}</span> //트윗 생성 일자
</div>
<div className='tweet__message'>{tweet.content}</div> //트윗 메시지
</div>
</li>
);
})}
</ul>
);
};
→ 아래 레퍼런스 코드는 isParkHacker, tweetUserNameClass등의 변수 선언을 통해 가독성을 좀 더 높이고 있다.
const Tweets = () => {
return (
<ul className="tweets">
{dummyTweets.map((tweet) => {
const isParkHacker = tweet.username === 'parkhacker';
const tweetUserNameClass = isParkHacker
? 'tweet__username tweet__username--purple'
: 'tweet__username';
return (
<li className="tweet" key={tweet.id}>
<div className="tweet__profile">
<img src={tweet.picture} />
</div>
<div className="tweet__content">
<div className="tweet__userInfo">
<span className={tweetUserNameClass}>{tweet.username}</span>
<span className="tweet__createdAt">{tweet.createdAt}</span>
</div>
<div className="tweet__message">{tweet.content}</div>
</div>
</li>
);
})}
</ul>
);
};
오늘은 처음으로 리액트를 배웠다. 이론 내용을 보고는 좀 알 것도 같았는데, 막상 과제를 해보니 뭔가 너무 복잡하게 느껴졌다. 라이브러리, 특히 리액트라는 것이 분명 더 편한 개발 환경을 제공하니 널리 사용되는 것일 텐데, 아무래도 리액트 문법이 익숙하지 않아 그런 것 같다. 페어 분의 도움을 받아 하나하나 직접 코드를 작성해 보며 내 기초가 조금 부족하다는 느낌도 들었다. 이번 설 연휴에는 부족한 기초 부분을 복습하고 리액트와 더 친해지는 시간을 보내야겠다.