오늘은 트위틀러 어드벤스드에 관해 풀어보자.
질문은 딱 두가지다.
<select>
, <option
>으로 트윗 작성한 사용자를 조회할 수 있는 드롭다운(Dropdown) 메뉴를 만듭니다.우선 이 기능을 사용하기 위해서는 클릭된 이름의 값을 받아올 수 있어야 하고, 유저 이름을 클릭했을 때 그 이름을 가진 트윗만 필터해서 트윗창에 보여야 한다.
//트윗을 fileter 로 거르기 위해 useState설정
const [filteredTweets, setFilteredTweets] = useState(tweets);
//옵션에 관련된 상태를 설정하기 위해서 useState 설정
const [isFiltered, setIsFiltered] = useState(false);
//tweet 내부의 username을 map을 통해 뽑아오기 위한 func 할당
const filteredUsername = tweets.map(tweet => tweet.username);
/* ... 생략*/
//옵션을 클릭했을 때 setIsFiltered 의 useState 를 변경해주기 위한 event 할당
const handleFilter = (event) => {
console.log(event.target.value);
if(event.target.value === 'All'){
setIsFiltered(false);
setTweets(tweets);
//event.target.value 즉 옵션의 결과값이 All일때에는
//setIsFiltered의 useState 상태가 false이다. 이 때,
//setTweets에 따로 가공하지 않은 tweets를 보여지게 만든다.
}else{
const filtered = tweets.filter(tweet => tweet.username === event.target.value);
setIsFiltered(true);
setFilteredTweets(filtered);
//event.target.value의 값이 tweet.username 즉 옵션으로 클릭 한 값이 tweet에 저장된 username 과 같을 시,
//setIsFiltered의 useState는 true;로 바뀌게 되고,
//setFilteredTweets로 인해 가공된 tweet으로 화면에 나타나게 된다.
}
}
/* ... 생략*/
//select 창을 구현해주자.
<select onChange={handleFilter}>
<option>All</option>
{filteredUsername.map((username, idx) => {
return <option key={idx}>{username}</option>
})}
</select>
/* ... 생략*/
//삼항연산자를 통해서 Tweets하위 컴포넌트인 Tweet 컴포넌트에 props를 전달해주면 option click 을 통한 기능구현이 완성된다.
{isFiltered ? // isFiltered true일때는 filteredTweets (username과 일치하는) 렌더링
filteredTweets.map(tweet => {
return <Tweet tweet={tweet} key={tweet.id} handleDelete={handleDelete}></Tweet>
})
: tweets.map(tweet => { //// isFiltered false일때는 tweets 렌더링
return <Tweet tweet={tweet} key={tweet.id} handleDelete={handleDelete}></Tweet>
})
}
// Tweet 에 기능하는 함수에 hadleDelete를 추가해주도록 하자.
const Tweet = ({ tweet, handleDelete }) => {
/* 생략 */
<button onClick={() => handleDelete(tweet.id)}>delete</button>
{/* 상태갱신함수 -> 상위컴포넌트 Tweets.js 하위컴포넌트 Tweet */}
/* 생략 */
};
//그리고 이제 버튼을 눌렀을 때 함수를 만들어 주자
const handleDelete = (deleteId) => {
if(isFiltered){
const deleted = filteredTweets.filter(tweet => tweet.id !== deleteId);
//filteredTweets, tweets
setFilteredTweets(deleted);
const deletedTweets = tweets.filter(tweet => tweet.id !== deleteId);
setTweets(deletedTweets);
// 리렌더링
}else{
const deleted = tweets.filter(tweet => tweet.id !==deleteId);
setTweets(deleted);
}
}