코드스테이츠 프론트엔드 부트캠프-Section2 React 이용하여 간단한 Tweetler 제작

그래도 아무튼 개발자·2023년 3월 28일
0

Front_End

목록 보기
8/12
post-thumbnail

Section2에서는 React를 메인으로 학습하였다.
이번에는 React를 이용하여 유사 SNS를 만들어보자

늘 그랬듯 결과물부터~

아 물론 데이터들은 실제 서버에서 불러온 것이 아닌 Dummy Data를 활용하였다.

메인 js파일은 7개로 구성된다.

  1. App.js
  2. Tweets.js
  3. Tweet.js
  4. MyPage.js
  5. Footer.js
  6. Sidebar.js
  7. About.js

App.js

import React from 'react';
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Sidebar from './Sidebar';
import Tweets from './Pages/Tweets';
import MyPage from './Pages/MyPage';
import About from './Pages/About';

import './App.css';
import './global-style.css';

const App = (props) => {
  return (
  <BrowserRouter>
    <div className="App">
      <main>
        <Sidebar />
        <section className="features">
          <Routes>
            <Route path="/" element={<Tweets />}></Route>
            <Route path="/about" element={<About />}></Route>
            <Route path="/mypage" element={<MyPage />}></Route>
          </Routes>
        </section>
      </main>
    </div>
  </BrowserRouter>
  );
};

export default App;

react-router-dom에 있는 BrowserRouter, Routes, Route, Link를 이용한다. 대부분의 파일에서 react-router-dom을 이용하기에 그냥 모든 파일에 한번에 import하였다..😊
Route를 이용하여 Tweets와 About, MyPage를 각각 설정하였고, 모든 리턴값을 BrowserRouter로 묶어놓았다.

Tweets.js (코드가 길어서 일부만...)

const Tweets = () => {
  const [tweets, setTweets] = useState(dummyTweets);
  const [msg, setMsg] = useState("");
  const [username, setUserName] = useState("");
  const handleButtonClick = (event) => {
    const tweet = {
      id: tweets.length+1,
      username: username,
      picture: `https://randomuser.me/api/portraits/women/${getRandomNumber(
        1,
        98
      )}.jpg`,
      content:msg,
      createdAt: '2022-02-24T16:17:47.000Z',
      updatedAt: '2022-02-24T16:17:47.000Z',
    };
    setTweets([tweet, ...tweets])
  };

  const handleChangeUser = (event) => {
    setUserName(event.target.value);
  };

  const handleChangeMsg = (event) => {
    setMsg(event.target.value);
  };

여기서는 React 내부에 있는 useState를 사용하였다. 새로 입력되는 Tweet 설정과 handleChangeUser, handleChangeMsg를 통해 새로운 Tweet을 입력하고 버튼을 누르면 리스트에 입력되게끔 만들었다.

    <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}
                ></input>
                <textarea className="tweetForm__input--message" onChange={handleChangeMsg} placeholder="text area"></textarea>
              </div>
              <div className="tweetForm__count" role="status">
                <span className="tweetForm__count__text">
                  {'total: '+tweets.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>
      <div className="tweet__selectUser"></div>
      <ul className="tweets" id="tweet.id">
        {tweets.map((el) => { 
          return (
            <Tweet key={el.id} tweet={el} />
          )})}
      </ul>
      <Footer />
    </React.Fragment>

tweetForm 내부의 다양한 클래스들을 통해 tweet 메인 창을 관리하였다. 여기서 onChange 메서드를 활용하여 아까 만들어놓았던 useState를 통해 user와 msg가 실시간으로 바뀌도록 구현하였다. 그밖의 부분은 그냥 코드를 읽으면 알 수 있는 부분이니 패스~

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

export default Tweet;

Tweets 창에서 각각의 Tweet들이 가지고있는 클래스와 속성, 표시항목들은 이렇게 따로 Tweet.js에서 선언하였다. Tweet들의 양이 많아질 경우를 대비
username과 date, message가 포함된다.

About.js

const About = (props) => {
  return (
    <section className="aboutTwittler">
      <div className="aboutTwittler__container">
        <div className="aboutTwittler__wrapper">
          <div className="aboutTwittler__detail">
            <p className="aboutTwittler__detailName">React Twittler Info</p>
          </div>
        </div>
      </div>
      <div className="aboutTwittler__content">
        <i className="fas fa-users"></i>
        <p>나만의 Twittler 소개페이지를 꾸며보세요.</p>
      </div>
      <Footer />
    </section>
  );
};

export default About;

이건 아직 크게 꾸민건 없다. 추후에 다른 SNS처럼 계정설정, 앱설정, 알림, 친구목록 등을 들어갈 수 있는 메뉴로 개발하고 싶긴 하다.

MyPage.js

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>
            <p>28 팔로워 100 팔로잉</p>
          </div>
        </div>
      </div>
      <ul className="tweets__mypage">
        <Tweet tweet={filteredTweets[0]}/>
      </ul>
      <Footer />
    </section>
  );
};

export default MyPage;

MyPage로 들어갔을 때 계정 주인이 'Parkhacker'인 것으로 가정하고, Dummy Data에 있는 ParkHacker를 필터로 찾아내서 MyPage 프로필을 생성해보았다. 우선 Dummy Data에 Parkhacker가 작성한 트윗은 1개 뿐이기에 filteredTweets[0]만 했지만, 글이 여러개일 경우에도 이는 반복문으로 충분히 구현이 가능하다💪

Footer.js

const Footer = () => {
  return (
    <footer>
      <div>Footer Area</div>
    </footer>
  );
};

export default Footer;

일반적인 어플이나 홈페이지를 보면 하단에 따로 공간이 있는 경우가 있다. 그러한 경우를 반영해서 그냥 간단하게 추가해보았다.

Sidebar.js

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>
  );
};

export default Sidebar;

상단의 결과물을 보면 왼쪽에 Sidebar를 생성해서 mypage나 about창을 옮겨다닐 수 있도록 구현하였다. 버튼이 눌렸을 때 어디로 이동할 지에 대한 Link를 Sidebar.js에서 구현하였다.

css나 다른 추가기능은 조금 더 손볼 예정이다 🫡🫡

0개의 댓글