๐Ÿ‘€๋ฐ˜๋”ง๋ถˆ์ด ๊ณผ์ œ์ œ์ถœ

๋Œ๋ฆฌ์˜ ํ•˜๋ฃจยท2023๋…„ 1์›” 27์ผ
0

์š” ๊ทผ๋ž˜ react๋ฅผ ๊ณ„์† ์—ด์‹ฌํžˆ ์ตํžˆ๋Š”์ค‘์ด๋‹ค๐Ÿ˜Ž
์ž ์ž๋Š” ์‹œ๊ฐ„์ด ์•„๊นŒ์šด๊ฒŒ ์ด๋Ÿฐ ๊ธฐ๋ถ„์ผ๊นŒ๐Ÿ˜” ํ›„ํ›„...

์•„๋ฌดํŠผ ๊ฐ์„คํ•˜๊ณ , react์—์„œ ๊ฐ€์žฅ ํ—ท๊ฐˆ๋ฆฌ๋Š” ์ ์€ ์•„๋ฌด๋ž˜๋„ props๋ž‘ useState๊ฐ€ ์•„๋‹๊นŒ ์‹ถ๋‹ค.
๋‘ ์š”์†Œ์˜ ๊ฐœ๋…์ ์ธ ์ฐจ์ด์ ์€,

  • state : ๋ณ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’, ์œ ๋™์  , ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ ์ค‘ ๋‚ด๋ถ€์—์„œ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’
  • props : ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’, ํ•จ๋ถ€๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์—†๋Š” ์ฝ๊ธฐ์ „์šฉ๊ฐ์ฒด

react์—์„œ๋Š” props,useState์‚ฌ์šฉ์ด ๋นˆ๋ฒˆํ•œ๋งŒํผ, ์ค‘์š”ํ•œ ๊ฐœ๋…์ด ์•„๋‹์ˆ˜์—†๋‹ค.

๋ฐ‘์˜ ์ฝ”๋“œ๋“ค์€ ํŠธ์œ„ํ„ฐ์˜ ๋‚ด์šฉ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณธ๊ฑด๋ฐ, ์ž‘์„ฑ์ž๊ฐ€ ์ ์€ form์„ ํŠธ์œ—์— ํฌํ•จ์‹œ์ผœ์„œ ๋‚ด๋ณด๋‚ด๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

์ด๋ฒˆ ๊ณผ์ œ์˜ ์ฝ”๋“œ๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ๋‚ด๊ฐ€ ์•Œ๊ฒŒ๋œ ์ ์„ ์ญ‰ ์ ์œผ๋ฉฐ ์ƒ๊ธฐ์‹œ์ผœ๋ด์•ผ๊ฒ ๋‹ค.
โŒ์ฝ”๋“œ ์•ˆ์— ์žˆ๋Š” //์ˆซ์ž๋Š” ๋ฌด์‹œํ•ด์ฃผ์„ธ์š”! ์„ค๋ช…์„ ๋ง๋ถ™์ด๋ ค๊ณ  ์ฝ”๋“œ์— ์ง์ ‘ ์‚ฝ์ž…ํ•œ ์ˆซ์ž์ž…๋‹ˆ๋‹ค.

//App.js
import React from 'react';
import {BrowserRouter, Routes, Route} from 'react-router-dom';//1

import Sidebar from './Sidebar';
import Tweets from './Pages/Tweets';
import About from './Pages/About';
//2
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 path='/about' element={<About />}/>  
            <Route path='/mypage' element={<MyPage />} />
          </Routes>
        </section>
      </main>
    </div>
    </BrowserRouter>
  );
};

export default App;
  • //1 : react์— ํ•„์š”ํ•œ {BrowserRouter, Routes, Route}์„ import
  • //2 : ๊ฐ๊ฐ์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ import๋กœ ๊ฐ€์ ธ์™€์„œ Routes ์•ˆ์— Route๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์žˆ๋‹ค.
//Tweet.js
import React from 'react';
import './Tweet.css';

const Tweet = ({ tweet }) => { //1
  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;
  • ์œ„์˜ ์ฝ”๋“œ๋Š” ํŠธ์œ—์˜ ํ˜•์‹์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ๋‹ค. Tweet์„ defaultํ•˜๊ณ  ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ prop์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋‹ค.
    const Tweet = ({ tweet }) ๋ถ€๋ถ„์„ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด, ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ
    Ex) <Tweet tweet={something} /> ์™€ ๊ฐ™์ด ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
//Tweet.js
import React, { useState } from 'react';
import Footer from '../Footer';
import Tweet from '../Components/Tweet';
import './Tweets.css';
import dummyTweets from '../static/dummyData';

const Tweets = () => {
  const [tweets, setTweets] = useState(dummyTweets) //1
  const [username, setUsername] = useState("");
  const [msg, setMsg] = useState("");
  const getRandomNumber = (min, max) => {
    return parseInt(Math.random() * (Number(max) - Number(min) + 2));
  };

  const handleButtonClick = (event) => {
    const tweet = {//2
      id: tweets.length + 1,
      username: username,
      picture: `https://randomuser.me/api/portraits/women/${getRandomNumber(
        1,
        98
      )}.jpg`,
      content: msg,
      createdAt: new Date().toLocaleDateString('ko-kr'), 
      updatedAt: new Date().toLocaleDateString('ko-kr'),
    };

    console.log([tweets])
    console.log([tweet,...tweets])  //๊ทธ๋ƒฅ tweet๋กœ ์“ฐ๋ฉด  ๋ฐฐ์—ด, ๊ฐ์ฒด, ๋ฌธ์ž์—ด์˜ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ๊บผ๋‚ด์ค€๊ฒŒ ์•„๋‹Œ ๊ทธ๋ƒฅ Array๋กœ ๋‚˜์˜จ๋‹ค.
    setTweets([tweet,...tweets]) //์ด๊ฑฐ ๋ฐฐ์—ด๋กœ ๋‚˜์˜ค๋Š”๊ฑฐ ๋งž์Œ []์•ˆ์— ๊ฐ์ฒด 6๊ฐœ์žˆ๋Š”๊ฑธ๋กœ ๋‚˜์˜ด//3
    
   
    //dummydata + ์ „์†ก๋œ ํŠธ์œ— = tweets
  };

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

  const handleChangeMsg = (event) => {
    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"
                  placeholder="your username here.."
                  className="tweetForm__input--username"
                  onChange={handleChangeUser}
                  value={username}
                ></input>

                <textarea
                  placeholder="write here.."
                  className="tweetForm__input--message"
                    onChange={handleChangeMsg}
                      value={msg}
                      >
                </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}>submit</button>
            </div>
          </div>
        </div>
      </div>
      <div className="tweet__selectUser"></div>
      <ul className="tweets">
        
        {tweets.map((value) => <Tweet key={value.id} tweet={value} />)}//4

      </ul>
      <Footer />
    </React.Fragment>
  );
};

export default Tweets;
  • //1 : usestate๋กœ ์„ค์ •ํ•ด์ค€ ๋ชจ์Šต์ด๋‹ค. tweets์„ dummy~๋กœ ์„ค์ •ํ•˜๊ณ ,
    useState ์ดˆ๊นƒ๊ฐ’์€ dummy~๋กœ ์„ค์ •ํ•ด์คฌ๋‹ค.
    ๊ทธ ๋ฐ‘์œผ๋กœ๋Š” ๊ฐ๊ฐ input๊ณผ textare๋ฅผ changeํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ €์žฅํ•˜๋Š” useState๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

  • //2 : submit ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด, ์ผ์–ด๋‚˜๋Š” event๋ฅผ ์ •๋ฆฌํ•ด๋†“์€ ๊ณณ์ด๋‹ค. const tweet์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์„ค์ •ํ•ด์„œ, ํผ์— ์ž‘์„ฑํ•˜๋Š” ์ž‘์„ฑ์ž์˜ id ๋“ฑ๋“ฑ์„ useState๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•œ๋‹ค. ํผ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ณณ์€ ๋ฐ‘์—์„œ ๋”ฐ๋กœ ์ž‘์„ฑํ•œ๋‹ค.

  • //3 : ์œ„์˜ useState๋ณ€์ˆ˜๋“ค์„ ์ž˜ ๊ธฐ์–ตํ•ด์•ผํ•œ๋‹ค. tweets๋Š” dummydata(๋”๋ฏธ๋ฐ์ดํ„ฐ)๋ผ์„œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋ฐ›์•„์˜ค๋Š” ๊ณณ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
    ๊ทธ๋ฆฌ๊ณ  ์ง์ ‘ ์„ค์ •ํ•œ ๋ณ€์ˆ˜ tweet์„ ํ•ฉ์ณ์„œ ํŠธ์œ—์„ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— tweets์— ๋‘˜์„ ํ•ฉ์น˜๋Š” ํ•จ์ˆ˜ setTweets๋ฅผ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•œ๋‹ค. tweets๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฉด ๋ฐฐ์—ด์ด ์ง์ ‘ ๋ฆฌํ„ด๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๊ธฐ์„œ๋Š” spread์—ฐ์‚ฐ์ž๋ฅผ ์จ์ค˜์•ผํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ž‘์„ฑ์ž๊ฐ€ ์“ด ํผ + ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ [์ž‘์„ฑ์ž๊ฐ€์“ด form + ...dummydata]ํ˜•์‹์˜ ํ•จ์ˆ˜๋กœ ๋ฐ›์•„์ค€ ํ›„ tweets์— ๋ฆฌ๋ Œ๋”๋งํ•˜๊ฒŒ ๋œ๋‹ค.

  • //4 : Tweet์˜ prop์„ ๋ฐ›์•„์™€์„œ map์œผ๋กœ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋กœ ๋งŒ๋“ ๋‹ค. ์—ฌ๊ธฐ์„œ prop์œผ๋กœ tweet์ด ์‚ฌ์šฉ๋˜๊ณ , map์˜ ์ธ์ž๊ฐ€ tweet์•ˆ์˜ ๋ฐ์ดํ„ฐ๋กœ ๋“ค์–ด๊ฐ€์„œ ๊ทธ๋ ค๋‚ธ๋‹ค.

๋‚ด๊ฐ€ props.texContent๋ผ๊ณ  ๊ณ ๋ฅธ์ด์œ ๋Š”, ๋ง‰์—ฐํ•˜๊ฒŒ Tweet ์•ˆ์— ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ€๋‹ˆ๊นŒ!
๋ผ๊ณ  ๋Œ€์ถฉ ์ƒ๊ฐํ•ด๋ฒ„๋ ธ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทผ๋ฐ ์ง€๊ธˆ ๋‹ค์‹œ ๋ณด๋‹ˆ๊นŒ, ์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ• ๊ฑฐ๋ฉด ์ฐจ๋ผ๋ฆฌ
Tweet.textcontent๋ฅผ ๊ณ ๋ฅด๋Š”๊ฒŒ ๋งž์ง€ ์•Š์•˜๋‚˜....์‹ถ๋‹ค;;
์•„๋ฌดํŠผ props.children์ด๋ผ๋Š” ๊ฐœ๋…์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณด์ž๋ฉด,

const Poet = (props) => {
return <ul>{props.children}</ul>
}
  • props.children์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์•˜๋‹ค.

์œ„๋ฅผ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ,

const Poet = ({children}) => {
return <ul>{children}</ul>
}

์ด๋ ‡๊ฒŒ prop์„ ๋นผ๊ณ  children์„ prop๊ทธ ์ž์ฒด๋กœ ์“ธ ์ˆ˜๋„ ์žˆ๋‹ค.

props.children์€ ์ฃผ๋กœ ์ž์‹ or html ์˜ component๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋Š”์ง€ ๋ชจ๋ฅผ ๋•Œ,
ํ™”๋ฉด์— ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

๋‘๋ฒˆ์งธ ์˜ค๋‹ต์€ ๋ณต์ˆ˜์ •๋‹ต์ธ์ค„ ๋ชจ๋ฅด๊ณ  ํ•˜๋‚˜๋งŒ ์ฒดํฌํ•ด๋ฒ„๋ ธ๋‹ค!
์ด ์ „ ๊ธ€์—์„œ๋„ ๋งํ–ˆ๋“ฏ์ด, onClick ์•ˆ์—๋Š” ํ•จ์ˆ˜๋กœ ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜, ์™ธ๋ถ€์—์„œ ํ•จ์ˆ˜ ์„ ์–ธ ํ›„ ๋„ฃ์–ด์ค˜์•ผ ํ•˜๊ธฐ๋•Œ๋ฌธ์—, D๋ฒˆ๋„ ๋งž๋Š” ์ •๋‹ต์ง€๋‹ค.

props๋Š” ๊ฐ์ฒด๋กœ ๋“ค์–ด์˜ค๊ฒŒ ๋œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์žŠ์ง€๋ง์ž!
A์™€ B๋Š” ๊ฐ๊ฐ ํ•จ์ˆ˜ ์„ ์–ธ์‹๊ณผ ํ‘œํ˜„์‹์œผ๋กœ ๋งŒ๋“ ๊ฒƒ์ด๊ณ ,
C๋Š” name์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์„ค์ • ํ›„ name์— "walli"๊ฐ’์„ ์„ค์ •ํ•ด์คฌ๋‹ค.
D๋Š” props๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด ์ค€ ํ›„ key์™€ value๊ฐ’์„ ์ •ํ•ด์คฌ๋‹ค.
๊ทธ ํ›„์— spread syntax๋กœ {name:"wailli"}๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋ชจ์Šต์ด๋‹ค.

์Œ.....์—ฌ๊ธฐ์„œ ๋ญ”๊ฐ€ ์ค‘์š”ํ•œ ๊ฑธ ๊นจ๋‹ฌ์€๊ฒƒ๊ฐ™๋‹ค.
props์— ๊ด€ํ•œ ์–ด์ง€๋Ÿฌ์šด ์ƒ๊ฐ์ด ์ข€ ์ •๋ฆฌ๋œ ๋Š๋‚Œ.
๊ธ€ ๋งจ ์œ„์—์„œ ๊ณต๋ถ€ํ•œ props.child์ฒ˜๋Ÿผ ์œ„ ๋ฌธ์ œ์˜ ๊ตฌ๋ฌธ๋„ ์ •๋ฆฌํ•ด๋ณด๋ฉด,

const Hello = ({name}) => <div>{name}</div>

์ด๋ ‡๊ฒŒ ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค.
D๋ฅผ ํ’€์–ด๋ณด๋ฉด, {...props}์€ {name: "walli"}๋กœ ๋‚˜์˜ค๊ฒŒ ๋˜์„œ, name์ด๋ผ๋Š” prop์„ ์ €์žฅํ•˜๊ฒŒ ๋œ๋‹ค. ์œ„์˜ ์˜ˆ์ œ์™€ ์ผ๋งฅ์ƒํ†ตํ•œ๋‹ค!

์•„๋ฌด๋ž˜๋„ ๊ฐ์ฒด๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์„ ๋‹ค์‹œ ๋˜์งš์–ด๋ณด๋Š” ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

//๋ฐฐ์—ด
let x = [1, 2, 3, 4, 5];
let [y, z] = x;
console.log(y); // 1
console.log(z); // 2
//๊ฐ์ฒด
//์˜ˆ์ œ1
let o = {p: 42, q: true};
let {p, q} = o;

console.log(p); // 42
console.log(q); // true

//์˜ˆ์ œ2
{a : 1}
const { a } = { a : 1 };
a = 1;

๊ทธ ์ „์˜ ๊ณผ์ œ์—์„œ๋„ ๋น„์Šทํ•œ ๊ฒฝ์šฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

const Tweet = ({ tweet }) => { //์ƒ๋žต }

์œ„์˜ component๋Š” tweet์ด๋ผ๋Š” prop์„ ๋ฐ›์•„์„œ ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ component์— ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

profile
์ง„ํ™”์ค‘์ธ ๋Œ๋ฆฌ์ž…๋‹ˆ๋‹ค :>

0๊ฐœ์˜ ๋Œ“๊ธ€