React 과제: tweetler

KoEunseo·2022년 8월 3일
0

코드스테이츠

목록 보기
11/45

01 React Router 설치

npm install react-router-dom@^6.3.0


02 App.js

Router DOM :: BrowserRouter, Routes, Route

import {BrowserRouter, Routes, Route } from 'react-router-dom';
const App = (props) => {
  return (
    <BrowserRouter>
      <div className = "App">
        <main>
          <Sidebar/>
          <section>
            <Routes>
              <Route path="/" element={<Tweets />}/>
              <Route path="/about" element={<About />}/>
              <Route path="/mypage" element={<MyPage />}/>
            </Routes>
          </section>
        </main>
      </div>
    </BrowserRouter>
  )
}

03 Sidebar.js

import {Link} from 'react-router-dom';
const Sidebar = () => {
  return (
    <section className="sidebar">
      <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>
  );
}

04 Footer.js

시멘틱 태그 사용하기


05 Tweet.js

props :: { tweet } 받아와서 뿌려주기

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">
            <span className="tweet__username">{tweet.username}</span>
            <span className="tweet__createdAt">{parsedDate}</span>
          </div>
        </div>
        <div className="tweet__message">{tweet.content}</div>
      </div>
    </li>
  );
};

  1. Tweet 컴포넌트를 따로 만들었다. Tweets랑 다름주의
  2. 날짜 형식을 .toLocaleDateString('ko-kr')를 사용해서 가공해 parsedDate에 할당해줌.
  3. Tweet파일에서 li에 key를 넣지 않는다. (map을 사용할때 넣어줌!)

06 About.js

data import해와서 뿌려주기

import dummyTweets from '../static/dummyData';
const MyPage = () => {
  const filteredTweets = dummyTweets.filter( tweet => {
    return tweet.username === 'parkhacker';
  })
  return (
    <section className="myInfo">
      <div className="myInfo__container">
        <div className="myInfo__wrapper">
          <div className="myInfo__profile">
            <img src={filteredTweets[0].picture}/>
          </div>
          <div className="myInfo__detail">
            <p className="myInfo__detailName">
              {filteredTweets[0].username} Profile
            </p>
          </div>
        </div>
      </div>
      <ul className="tweet__mypage">
        {filteredTweets.map(tweet => {
          return <Tweet key={tweet.id} tweet={tweet} />
        })}
      </ul>
      <Footer />
    </section>
  )
}

  1. filter() 사용해 username: 박해커 걸러주고 filteredTweets에 할당.
  2. ul 하위에 li(<Tweet/>) 리턴, 그런데 이제 map()을 사용한.
<Tweet tweet={filteredTweets[0]} /\> //박해커가 1개 이상의 글을 썼을때 불러오지 못한다.

07 Tweets

useState 사용하기

import React, { useState } from 'react';
import dummyTweets from '../static/dummyData';
const Tweets = () => {
  const [username, setUsername] = useState("parkhacker"); //username에 초기값으로 박해커 할당.
  const [msg, setMsg] = useState("");
  const [data, setData] = useState(dummyTweets); //data에 초기값 할당.
  const handleButtonClick = (event) => {
    const tweet = {
      id: data.length + 1,
      username: username,
      picture: `https://randomuser.me/api/portraits/men/98.jpg`,
      content: msg,
      createdAt: new Date(),
      updatedAt: new Date()
    };
    setData([tweet, ...data]);
    //unshift 사용하는 방법: 
    //const newTweets = tweets.slice(); 
    //newTweets.unshift(tweet); //새로운 배열을 생성해서 배열앞에 추가
    //setData(newTweets);
  }
  const handleChangeUser = (event) => {
    setUsername(event.target.value);
  };
  const handleChangeMsg = (event) => {
    setMessage(event.target.value);
  };
  return (
    <React.Fragment>
      <div className="tweetForm__container">
        <div className="tweetForm__wrapper">
          <div className="tweetForm__profile">
            <img src="https://randomuser.me/api/portraits/men/98.jpg" />
          </div>
          <div className="tweetForm__inputContainer">
            <div className="tweetForm__inputWrapper">
              <div className="tweetForm__input">
                <input
                  type="text"
                  placeholder="your username here.."
                  className="tweetForm__input--username"
                  onChange={handleChangeUser}
                  value={username}></input>
                <textarea
                  placeholder="여기는 텍스트 영역입니다."
                  className="tweetForm__input--message"
                  onChange={handleChangeMsg}
                  value={msg}></textarea>
              </div>
              <div className="tweetForm__count" role="status">
                <span className="tweetForm__count__text">
                  {'total: ' + data.length}
                </span>
              </div>
            </div>
            <div className="tweetForm__submit">
              <div className="tweetForm__submitIcon"></div>
              <button className="tweetForm__submitButton" onClick={handleButtonClick}>
                Tweet
              </button>
            </div>
          </div>
        </div>
      </div>
      <ul className="tweets">
        {data.map((tweet) => {
          return (<Tweet tweet={tweet} key={tweet.id}/>)
        })}
      </ul>
      <Footer />
    </React.Fragment>
  );
}

useState로 state 활용하기

  1. [state 저장 변수, state 갱신 함수] = useState(초기값)
    state값은 직접 바꾸려고 하면 안됨. 함수로 바꿔야한다.
  2. onClick 이벤트핸들러
    버튼을 누르면 온클릭이벤트가 발생하고, tweet 객체에 작성한 데이터를 담는다.
    갱신함수에 배열형태로 새tweet변수, ...data를 전달한다.
    ...data는 깊은복사를 통해 같은 주소값으로 인식하지 않게 하기 위함!
    ❌ 같은주소로 인식하게 되면 리렌더링이 되지 않는다.
  3. onChange 이벤트핸들러
    변화가 생기면 온체인지이벤트 발생, 갱신함수에 해당 값을 전달한다.
  4. ul태그 내에 <Tweet/> 매핑. map()을 쓰기 때문에 key값을 할당한다.

profile
주니어 플러터 개발자의 고군분투기

0개의 댓글