본문 바로가기
개인공부/반딧불

[react] twittler-state-props 의사코드

by 뭉지야 2023. 1. 27.
728x90

sidebar.js

import React from 'react';
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>
);
};
export default Sidebar;
/* 의사코드포함 */
import React from 'react';
import { Link } from 'react-router-dom';   
//Link컴포넌트가 쓰일거라서 작성한다.
const Sidebar = () => {
return(
<section className="sidebar">  
//사이드바에 밑의 아이콘들이 존재한다
<Link to="/"><i className="far fa-comment-dots"></i></Link>
//link는 to속성을 이용해서 path주소를 연결해준다.
//tweet아이콘의 link컴포넌트는 /으로 연결된다. 이게 첫화면이된다.
<Link to="/about"><i className="far fa-question-circle"></i></Link>
//about아이콘의 link컴포넌트는 /about으로 연결된다
<Link to="/mypage"><i className="far fa-user"></i></Link>
//mypage아이콘의 link컴포넌트는 /mypage으로 연결된다.
</section>
);
};
export default Sidebar; //import했으니까 마지막에 export해준다.

 


Footer

import React from 'react';
const Footer = () => {
return <footer></footer>;
//시멘틱요소 footer가 포함되었다
};
export default Footer;

Tweet

import React from 'react';
import './Tweet.css';

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;
 /* 의사코드포함 */
import React from 'react';
import './Tweet.css';
//tweet.css 땡겨온다
//지금 이 tweet부분은 tweets중에서 한명의 내용이 뜨는 작은 컴포넌트이다.
const Tweet = ({ tweet }) => {
const parsedDate = new Date(tweet.createdAt).toLocaleDateString('ko-kr');
//날짜표기를 parsedDate라는 변수로 지정했다.
return (
<li className="tweet" id={tweet.id}>
<div className="tweet__profile"> //프로필부분에 사진이있다 그 사진이picture.
<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>//더미데이터에서content부분이 메세지.
</div>
</li>
);
};
export default Tweet;

About

import React from 'react';
import Footer from '../Footer';
import './About.css';

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;

 

/* 의사코드포함 */
import React from 'react';
import Footer from '../Footer';
//about에서 footer파일은 한폴더 올라가야해서 ..
//하단에 footer시멘틱요소 하기위해 여기에 쓰고 저밑에 <Footer />한번더 쓴다
import './About.css';
//about css 불러온다.
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 />
//하단에 시멘틱footer요소위해 작성.
</section>
);
};

export default About;

 

Mypage

import React from 'react';
import Footer from '../Footer';
import Tweet from '../Components/Tweet';
import './MyPage.css';
import dummyTweets from '../static/dummyData';

const MyPage = () => {
  // TODO : 주어진 트윗 목록(dummyTweets)중 현재 유져인 parkhacker의 트윗만 보여줘야 합니다.
  const filteredTweets = dummyTweets.filter((tweet) =>  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]}/>   
        {/* TODO : 주어진 트윗 목록(dummyTweets)중 현재 유져인 parkhacker의 트윗만 보여줘야 합니다. */}
      </ul>
      <Footer />
    </section>
  );
};

export default MyPage;
/* 의사코드포함 */
import React from 'react';
import Footer from '../Footer';
import Tweet from '../Components/Tweet';
//footer처럼 한폴더 위로 올라가서 components안에 들어가서 tweet있어서
import './MyPage.css';
import dummyTweets from '../static/dummyData';
//필터때 더미데이터가 쓰이니까 불러온다.

const MyPage = () => {
const filteredTweets = dummyTweets.filter((tweet) =>  tweet.username === 'parkhacker');
//더미데이터에서 username이 박해커인것만 골라낸다. 그게 filteredTweets이라는 변수가진다.
return (
<section className="myInfo">
<div className="myInfo__container">
<div className="myInfo__wrapper">
<div className="myInfo__profile">
<img src={filteredTweets[0].picture} />
//필터되서 박해커만 있으니까 인덱스는0이다.
</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]}/> 
//앞의 tweet는 컴포넌트명(footer같은) 뒤의 tweet는 속성명이다.(classname같은거) 
</ul>
<Footer />
//하단에 시멘틱요소 
</section>
);
};
export default MyPage; 
//이것으로 mypage를 마친다는 의미로 생각하면 될듯

Tweets

// TODO : useState를 react로 부터 import 합니다.
import React, { useState } from 'react';
import Footer from '../Footer';
import Tweet from '../Components/Tweet';
import './Tweets.css';
import dummyTweets from '../static/dummyData';

const Tweets = () => {
  // TODO : 새로 트윗을 작성하고 전송할 수 있게 useState를 적절히 활용하세요.
  const getRandomNumber = (min, max) => {
    return parseInt(Math.random() * (Number(max) - Number(min) + 2));
  };

  const [tweets, setTweets] = useState(dummyTweets);
  const [user, setUser] = useState("");
  const [msg, setMsg] = useState("");

  const handleButtonClick = (event) => {
    const tweet = {
      id: Tweets.length+1,
      username: user,
      picture: `https://randomuser.me/api/portraits/women/${getRandomNumber(
        1,
        98
      )}.jpg`,
      content: msg,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    // TODO : Tweet button 엘리먼트 클릭시 작동하는 함수를 완성하세요.
    // 트윗 전송이 가능하게 작성해야 합니다.
    setTweets([tweet, ...tweets])
    setMsg(' ');
  };

  const handleChangeUser = (event) => {
    // TODO : Tweet input 엘리먼트에 입력 시 작동하는 함수를 완성하세요.
    setUser(event.target.value)               
  };

  const handleChangeMsg = (event) => {
    // TODO : Tweet textarea 엘리먼트에 입력 시 작동하는 함수를 완성하세요.
    setMsg(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"
                  defaultValue="parkhacker"
                  placeholder="your username here.."
                  className="tweetForm__input--username"
                  onChange= {handleChangeUser}
                  value={user}
                ></input>
                {/* TODO : 트윗을 작성할 수 있는 textarea 엘리먼트를 작성하세요. */}
                <textarea
                  defaultValue={""}
                  placeholder="your message here.."
                  className="tweetForm__input--message"
                  onChange= {handleChangeMsg}
                  value={msg}
                ></textarea>
              </div>
              <div className="tweetForm__count" role="status">
                <span className="tweetForm__count__text">
                  {/* TODO : 트윗 총 개수를 보여줄 수 있는 Counter를 작성하세요. */}
                  {'total: ' + tweets.length}
                </span>
              </div>
            </div>
            <div className="tweetForm__submit">
              <div className="tweetForm__submitIcon"></div>
              {/* TODO : 작성한 트윗을 전송할 수 있는 button 엘리먼트를 작성하세요. */}
              <button className="tweetForm__submitButton" onClick={handleButtonClick}>Tweet</button>
            </div>
          </div>
        </div>
      </div>
      <div className="tweet__selectUser"></div>
      <ul className="tweets">
        {/* TODO : 하나의 트윗이 아니라, 주어진 트윗 목록(dummyTweets) 갯수에 맞게 보여줘야 합니다. */}
         {tweets.map((el) => <Tweet tweet ={el}/>)}
      </ul>
      <Footer />
    </React.Fragment>
  );
};

export default Tweets;
/* 의사코드포함 */
import React, { useState } from 'react';
//useState사용하기위해 react로부터 불러왔다.
import Footer from '../Footer';
import Tweet from '../Components/Tweet';
import './Tweets.css';
import dummyTweets from '../static/dummyData';

const Tweets = () => {
const getRandomNumber = (min, max) => {
return parseInt(Math.random() * (Number(max) - Number(min) + 2));
};

const [tweets, setTweets] = useState(dummyTweets);
//기존이tweets, 새로운내용추가되면 setTweets.
const [user, setUser] = useState("");
//user가 state변수, setUser는 변수를 갱신할수있는함수이다. 초기값은 비어있다.
const [msg, setMsg] = useState("");

const handleButtonClick = (event) => {
const tweet = {
id: Tweets.length+1,
username: user,
picture: `https://randomuser.me/api/portraits/women/${getRandomNumber(1,98)}.jpg`,
content: msg,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
setTweets([tweet, ...tweets])
//빈배열에다가 기존tweets를 넣고 spread문법을쓰고, 새로운것도 추가한다는거다.
//기존의 데이터가tweets다. 새로운 tweet가 위에 위치한다.
setMsg(' ');
//이거랑 value=msg도 추가하면 입력하고 엔터치면 입력창 깨끗해지는 기능한다.
};
const handleChangeUser = (event) => {
setUser(event.target.value)};              
//target은 input태그가 된다. 이벤트가 발생하는 엘리먼트의 값을 가져온다
//value안쓰면 input문장을 가져온다
const handleChangeMsg = (event) => {
setMsg(event.target.value)};          //target은 textarea태그가 된다
 
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"
defaultValue="parkhacker"
placeholder="your username here.."
className="tweetForm__input--username"
onChange= {handleChangeUser}
//onchange이벤트가 발생하면 setUser된 input값을 불러온다.
value={user}
></input>
<textarea
defaultValue={""}
placeholder="your message here.."
className="tweetForm__input--message"
onChange= {handleChangeMsg}
//onChange이벤트가 발생하면 setMsg된 textarea값을 불러온다.
value={msg}
//이거추가하면 입력창 깨끗해진다!
></textarea>
</div>
<div className="tweetForm__count" role="status">
<span className="tweetForm__count__text">
{'total: ' + tweets.length}
//tweets의 총 개수를 보여준다. 
</span>
</div>
</div>
<div className="tweetForm__submit">
<div className="tweetForm__submitIcon"></div>
<button className="tweetForm__submitButton" onClick={handleButtonClick}>Tweet</button>
//Tweet버튼을 클릭하면 handleButtonClick함수가 작동한다.
</div>
</div>
</div>
</div>
<div className="tweet__selectUser"></div>
<ul className="tweets">
{tweets.map((el) => <Tweet tweet ={el}/>)}
//앞의tweet은컴포넌트명이고 뒤의 tweet은 속성명이다
</ul>
<Footer />
</React.Fragment>
);
};

export default Tweets;

App.js

import React from 'react';
// TODO : React Router DOM을 설치 후, import 구문을 이용하여 BrowserRouter, Routes, Route 컴포넌트를 불러옵니다.
import {BrowserRouter, Routes, Route } from 'react-router-dom';

import Sidebar from './Sidebar';
import Tweets from './Pages/Tweets';
import About from './Pages/About';
import MyPage from './Pages/MyPage';
// TODO : MyPage, About 컴포넌트를 import 합니다.

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


const App = (props) => {
  return (
     <BrowserRouter>
    <div className="App">
      <main>
        <Sidebar />
        <section className="features">
          {/* TODO : 유어클래스를 참고해서, 테스트 케이스를 통과하세요.
            TODO : React Router DOM 설치 후 BrowserRouter, Routes, Route의 주석을 해제하고 Routes, Route 컴포넌트를 적절하게 작성합니다. */}
          {/* Route 예시: <Route path="/" element={<Tweets />}></Route> */}
            <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;

 

/* 의사코드포함 */
import React from 'react';
import {BrowserRouter, Routes, Route } from 'react-router-dom';
//react router의 컴포넌트들(browserrouter, routes, route)을 사용하기위해 불러온다.
import Sidebar from './Sidebar';
import Tweets from './Pages/Tweets';
import About from './Pages/About';
import MyPage from './Pages/MyPage';

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

const App = (props) => {
return (
<BrowserRouter>
//browserRouter컴포넌트를사용할거다
<div className="App">
<main>
<Sidebar />
//이거랑 import에서 sidebar부분 지우면 아예 앱에서 sidebar사라진다
<section className="features">
<Routes> 
//routes는 route를 감싸고있어야한다.
<Route path="/" element={<Tweets />}></Route>
<Route path="/about" element={<About />}></Route>
//about메뉴를 누르면 path가 about으로 연결된다.
<Route path="/mypage" element={<MyPage />}></Route>
//Mypage메뉴를 누르면 path가 /mypage로 연결된다.
</Routes> 
</section>
</main>
</div>
</BrowserRouter>
);
};
export default App;

 

route컴포넌트는 path속성을 지정하여 해당 path에서 어떤 컴포넌트를 보여줄지 정한다. 근데 path가 /mypage여서 MyPage컴포넌트로 연결이 된다.

Link컴포넌트가 정해주는 url경로와 일치하는 경우에만 작동한다.

route태그안에 element속성으로 연결하고자 하는 컴포넌트를 넣어준다.

저기서는 그 컴포넌트가 MyPage였던거고  Tweets였던거.

path와 Link to가 일치하면 i className을 누르면 element컴포넌트(Tweets)로 연결이된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90

'개인공부 > 반딧불' 카테고리의 다른 글

객체지향프로그래밍  (0) 2023.01.16