TIL 10)React Tweet Intro Review

Hover·2023년 3월 27일
0

TIL

목록 보기
11/27

0. 완성 페이지



1.Router

router로 총 3개의 페이지 이동을 만들어야한다.

  1. 전체적인 글 내용이 보이는 Tweets
  2. 내 정보를 보여주는 MyPage
  3. About

1) import를 통해 필요한 컴포넌트를 react-router-dom에서 불러온다.

import { BrowserRouter, Routes, Route } from "react-router-dom";

2)Router 사용 형식대로 jsx를 수정한다.

    <BrowserRouter>
            <Routes>
              <Route path="/" element={<Tweets />}></Route>
              <Route path="/mypage" element={<MyPage />}></Route>
              <Route path="/about" element={<About />}></Route>
            </Routes>
    </BrowserRouter>

// Routes와 관련없는 코드는 삭제했음!

path에 경로를 입력하고 element에 해당 경로에 맞는 component를 매칭시켜준다.

2. MyPage

mypage의 요구사항은 현재 유저인 parkhacker의 트윗만 보여지는 것이다.

따라서, dummydata중 사용자가 parkhacker인 배열만 filter해서 mypage에 렌더링시킨다.

1) 데이터 필터링

  const filteredTweets = dummyTweets.filter((it) => {
    return it.username === "parkhacker";
  });

filteredTweets에 username이 parkhacker인 배열만 들어갔다.

배열의 갯수가 하나라도 배열이기때문에 배열처럼 사용 해줘야함!!!

2) 필터링 된 배열 사용

          <div className="myInfo__profile">
            <img src={filteredTweets[0].picture} />
          </div>
          <div className="myInfo__detail">
            <p className="myInfo__detailName">
              {filteredTweets[0].username} Profile
            </p>
            <p>28 팔로워 100 팔로잉</p>
          </div>

필터링 된 배열 filteredTweets를 다음과 같이 사용해준다.

위와 같이 해서 상단에 현재 유저의 프로필을 만들어줬으면, 하단에 Tweet모양으로도 만들어줘야한다.

      <ul className="tweets__mypage">
        <Tweet tweet={filteredTweets[0]} />
      </ul>

하단의 tweet 모양은 tweet컴포넌트로 필터링된 배열을 보낸다.

3.tweets

트윗 내용들이 보여지는 페이지다.

총 3개의 기능이 있다.

1.새로운 트윗을 입력 가능
2.새로 입력한 트윗을 전송 가능
3.트윗 목록을 최신순으로 정렬해서 보여지게함.

1) 신규 트윗 입력

우선 useState로 변경되는 값(상태)을 선언해준다.

  const [newUsername, setNewUsername] = useState("");
  const [newTweetText, setNewTweetText] = useState("");

이후 html 폼에서 onChange 옵션을 통해 setState와 연결시켜준다.

//jsx
<input ... onChange={handleChangeUser} />
<textarea ... onChange={handleChangeMsg} />

//function
const handleChangeUser = (e)=>{
  setNewUsername(e.target.value);
};

const handleChangeMsg = (e)=>{
  setNewTweetText(e.target.value)
};

2) 신규 트윗 전송 + 순서 정렬

처음에는 신규 트윗 배열에 그냥 push해주면 될 거 같아서 이 방법을 써봤다.

하지만, 위 방법은 객체의 불변성을 침해한다.

따라서, 나는 새로운 객체 배열을 선언해 기존의 트윗을 대신해서
새로운 객체 배열을 useState로 상태 관리하는 방법을 선택했다.

우선, 신규 객체 배열을 useState로 선언해준다.

const [TweetsData, setTweetsData] = useState(dummyTweets);

default값은 기존 배열의 값으로 정해줬다.

그다음, html부분에 클릭 시 전송되는 option을 넣어줬다.

<button ... onClick={handleButtonClick} />

handleButtonClick 함수를 구현하였다.

  const handleButtonClick = (event) => {
    event.preventDefault();
    // 새로고침을 방지
    let time = new Date().toISOString();
    // 입력 시 현재 시간을 ISOString형식으로 변환
    const tweet = {
      content: newTweetText,
      createdAt: time,
      id: dummyTweets.length + 1,
      picture: "https://randomuser.me/api/portraits/men/98.jpg",
      updatedAt: time,
      username: newUsername,
    };
    //새로운 트윗이 될 객체
    
    let sortTweetsData = [...TweetsData, tweet];
    sortTweetsData.sort((a, b) => {
      return b.id - a.id;
    });
	// id값을 기준으로 오름차순으로 배열 재정렬
    
    setTweetsData(sortTweetsData);
    //setState로 정렬된 배열로 상태 업데이트
    setNewUsername("");
    setNewTweetText("");
    // 입력값들 초기화
    // html tag단의 value옵션을 바꿔주는것.
  };

마지막으로 위에서 새롭게 탄생한 배열을 map 함수를 사용해 tweet에 렌더링되게 만든다.

        {TweetsData.map((it) => {
          return <Tweet tweet={it} key={it.id} />;
        })}
// tweet.js
const Tweet = ({ tweet }) => {
  const parsedDate = new Date(tweet.createdAt).toLocaleDateString("ko-kr");

  return (
    <li className="tweet" id={tweet.id}>
      <div className="tweet__profile">
        <img src={tweet.picture} />
      </div>
      <div className="tweet__content">
        <div className="tweet__userInfo">
          <div className="tweet__userInfo--wrapper">
            {/* TODO : 유져 이름이 있어야 합니다. */}
            <span className="tweet__username">{tweet.username}</span>

            {/* TODO : 트윗 생성 일자가 있어야 합니다. parsedDate를 이용하세요. */}
            <span className="tweet__createdAt">{parsedDate}</span>
          </div>
        </div>
        <div className="tweet__message">{tweet.content}</div>
      </div>
    </li>
  );
};
profile
프론트엔드 개발자 지망생입니다

0개의 댓글