[React] React State와 Props를 이용한 Twittler 정리

Yuni·2022년 8월 3일
0

코드스테이츠

목록 보기
24/39

React Router DOM을 설치 후 import 구문을 이용하여 BrowserRouter, Routes, Route, Link 컴포넌트를 불러온다.

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

🤔 import할 때 왜 어떤 건 중괄호를 사용하고 어떤 건 사용하지 않을까? 출처
해당 컴포넌트에서 export할 때, export 뒤에 default 키워드를 붙여주면 다른 컴포넌트에서 import할 때 괄호를 써주지 않아도 된다. 또 변수명도 import한 컴포넌트에서 마음대로 지정할 수 있다.

라우터 역할을 하는 BrowserRouter 컴포넌트를 작성하고, 그 안에 경로를 매칭해주는 RoutesRoute, 그리고 경로를 변경하는 역할을 하는 Link를 작성한다.

<BrowserRouter>
    <div className="App">
      <main>
        <section className="sidebar">
        	// <Link>의 to 속성을 활용하여 <Route> 컴포넌트에 설정해 준 path 주소를 연결한다.
      		<Link to="/"><i className="far fa-comment-dots"></i></Link>
      		<Link to="/about"><i className="far fa-question-circle"></i></Link>
      		<Link to="/mypage"><i className="far fa-user"></i></Link>  
    	</section>
        <section className="features">
          <Routes>
          	// path로 경로를 설정해서 해당 경로로 접근하면 element에 작성한 컴포넌트로 연결해준다.
            <Route path='/' element={<Tweets/>}></Route>
            <Route path='/about' element={<About />}></Route>
            <Route path='/mypage' element={<MyPage />}></Route>
          </Routes>
        </section>
      </main>
    </div>
</BrowserRouter>

트윗을 작성하기 위해 useState로 사용자 이름과 메세지가 변경될 때마다 관리한다.

// useState 호출해서 state의 변수, 갱신 함수, 초기값을 지정한다.
 const [username, setUsername] = useState("");

const handleChangeUser = (event) => {
  	// event를 호출한 요소의 값을 가져온다.
	setUsername(event.target.value);
};

// input의 value가 변경될 때마다 호출될 함수를 지정한다.
<input
	type="text"
	placeholder="your username here.."
	className="tweetForm__input--username"
	onChange={handleChangeUser}
	value={username}
></input>

트윗 전송 버튼을 클릭했을 때 트윗 목록에 작성한 트윗을 추가하기위해 트윗들을 state로 관리한다.

const [tweets, setTweets] = useState(dummyTweets);

const handleButtonClick = (event) => {
  	// 새로 추가할 트윗을 객체로 선언하고 작성했던 내용들을 할당한다.
	const tweet = {id: ~, username: ~};

  	// 갱신 함수에 새 배열을 선언하고 새로 추가할 트윗과 기존 트윗을 spread 문법으로 펼쳐서 할당한다.
    setTweets([tweet, ...tweets]);
  	// let new
  
	// 트윗 전송 후 사용자 이름과 메세지를 비우기 위함
    setUsername("");
    setMsg("");
};

🤔 아래 코드처럼 unshift()를 써서 새 트윗을 기존 트윗에 추가해주면 안되나요?

tweets.unshift(tweet);
setTweets(tweets);

unshift()는 원본 배열을 변경하는 것이기 때문에 기존에 저장된 tweets와 현재 갱신 함수에 전달 인자인 tweets는 주소가 같다. set 갱신함수는 같은 주소값이면 갱신을 하지 않기 때문에 리렌더링이 안된다!

🖐 저는 unshift()를 사용하고 싶은데요

const newTweets = tweets.slice();
newTweets.unshift(tweet);
setTweets(newTweets);

unshift()를 사용하고 싶다면 위 코드처럼 tweets를 복사해 새 배열을 만들고(주소값이 달라짐) unshift()를 사용하면 된다

트윗들을 나열하기 위해 map을 사용해 tweets에서 꺼낸 각 tweet들을 Tweet 컴포넌트에 props으로 전달한다.

<ul className="tweets">
	{
		tweets.map(tweet => {
            return <Tweet tweet={tweet} key={tweet.id}></Tweet>
        })
	}
</ul>

Tweet 컴포넌트에서는 객체인 props를 전달받아 렌더링한다.

const Tweet = ({ tweet }) => {
  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">
            <span className="tweet__username">
            {tweet.username}
            </span>
            <span className="tweet__createdAt">
            {parsedDate}
            </span>
          </div>
        <div className="tweet__message">
          {tweet.content}
        </div>
      </div>
    </li>
  );
};
profile
배운 것을 기억하기 위해 기록합니다 😎

0개의 댓글