React ๊ธฐ์ดˆ (1) ๐Ÿฆ

forhreverยท2023๋…„ 3์›” 28์ผ
0

JSX

  • ํ•˜๋‚˜์˜ ์—˜๋ฆฌ๋จผํŠธ ์•ˆ์— ๋ชจ๋“  ์—˜๋ฆฌ๋จผํŠธ ํฌํ•จ
<div>
  <div>
    <h1>Hi</h1>
  </div>
  <div>
    <h1>hello</h1>
  </div>
</div>
  • ์—˜๋ฆฌ๋จผํŠธ ํด๋ž˜์Šค ์‚ฌ์šฉ ์‹œ, classname์œผ๋กœ ํ‘œ๊ธฐ
<div classname = "good">coding</div>
  • Javascript ํ‘œํ˜„์‹ ์‚ฌ์šฉ ์‹œ, ์ค‘๊ด„ํ˜ธ {} ํ•„์ˆ˜
function app {
    
   const name = "hong";
 
   return {
      <div>
         hello,{name}
      </div>
   };
}
  • ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘
function Hello() {
...
}

function HelloBye() {
   return <Hello />;
}
  • ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์—์„œ๋Š” if๋ฌธ์ด ์•„๋‹Œ ์‚ผํ•ญ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉ
<div>
  {
    (1 + 1 === 2) ? (<p>์ •๋‹ต</p>) : (<p>์˜ค๋‹ต</p>)
  }
</div>
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ HTML ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ‘œ์‹œํ•  ๋•Œ๋Š” "map()" ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
return (
    <div className="App">
      <h1>Hello JSX</h1>
      {posts.map((post) =>
        <div key={post.id}>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
        </div>
      )}
    </div>
  );

**key ์†์„ฑ**

  • React์—์„œ map()๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ ์‹œ, key ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์— ์žˆ๋Š” ์ฒซ๋ฒˆ์งธ ์—˜๋ฆฌ๋จผํŠธ์— ๋„ฃ์–ด์ค€๋‹ค.
function Blog() {
 
  const blogs = posts.map((post) => (
    <div key={post.id}>    // key ์†์„ฑ์„ ๋„ฃ์€ ์˜ˆ์‹œ
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  ));
  return <div className="post-wrapper">{blogs}</div>;
}

React-twittler-intro ๊ณผ์ œ

https://github.com/forhrever/fe-sprint-react-twittler-intro.git

Q : Font Awesome์„ ํ™œ์šฉํ•˜์—ฌ ํŠธ์œ— ๋ฉ”์‹œ์ง€ ์•„์ด์ฝ˜์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (className : "far fa-comment-dots").

const Sidebar = () => {
  return (
    <section className="sidebar">
      {/* TODO : ๋ฉ”์„ธ์ง€ ์•„์ด์ฝ˜์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. */}
      <i className = "far fa-comment-dots"></i> 
    </section>
  );
};

Q : dummyTweet๋กœ ์ „๋‹ฌ๋˜๋Š” ํŠธ์œ— ๊ฐœ์ˆ˜์™€ ์นด์šดํŠธ๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ex) total : 5

  • total๊ณผ ์ˆซ์ž๊ฐ€ ์ฝ˜ํ…์ธ ์— ํฌํ•จ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
const Counter = () => {
  return (
    <div className="tweetForm__input">
      <div className="tweetForm__inputWrapper">
        <div className="tweetForm__count" role="status">
           {/*TODO : dummyTweet๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. */}
          {'total:' + dummyTweets.length}
        </div>
      </div>
    </div>
  );
};

Q : Footer ์ปดํฌ๋„ŒํŠธ์˜ ํ›„์† ์—˜๋ฆฌ๋จผํŠธ๋กœ ์‹œ๋งจํ‹ฑ ์—˜๋ฆฌ๋จผํŠธ footer๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์‹œ๋ฉ˜ํ‹ฑ ์—˜๋ฆฌ๋จผํŠธ <footer>๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
const Footer = () => {
  return (
      <footer>
      <img id="logo" src={`${process.env.PUBLIC_URL}/codestates-logo.png`} />
      Copyright @ 2022 Code States
      </footer>
  );
};
// TODO : Footer ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋ฉ˜ํ‹ฑ ์—˜๋ฆฌ๋จผํŠธ footer๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Q : ํŠธ์œ— ์ €์ž์˜ ํ”„๋กœํ•„ ์‚ฌ์ง„์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • li.tweet ์—˜๋ฆฌ๋จผํŠธ์˜ ํ›„์† ์—˜๋ฆฌ๋จผํŠธ๋กœ <img> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dummyTweets์˜ ์ด๋ฏธ์ง€ ์ฃผ์†Œ ์ •๋ณด๋ฅผ ์ฐพ์•„์„œ <src> ์†์„ฑ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
const Tweets = () => {
  return (
    <ul className="tweets">
      {dummyTweets.map((tweet) => {
        return (
          <li className="tweet" key={tweet.id}>
            <div className="tweet__profile">
              <img src = {tweet.picture}></img>  // ๋ณ€๊ฒฝ ์ „ img class ...
            </div>
     .
     .
     .

Q : ์œ ์ € ์ด๋ฆ„์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • li.tweet ์—˜๋ฆฌ๋จผํŠธ์˜ ํ›„์† ์—˜๋ฆฌ๋จผํŠธ๋กœ <span> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dummyTweets์˜ ์œ ์ € ์ด๋ฆ„์„ <span>์˜ ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๋กœ ๋„ฃ์Šต๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ์ด๋ฆ„์€ tweet__username์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  .
  .
  .
<div className="tweet__content">
              <div className="tweet__userInfo">
                {/* TODO : ์œ ์ ธ ์ด๋ฆ„์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. */}
                <span className=tweet__username>{tweet.username}</span>
  .
  .
  .

Q : ํŠธ์œ— ์ƒ์„ฑ ์ผ์ž(yyyy. m. d.) ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • li.tweet ์—˜๋ฆฌ๋จผํŠธ์˜ ํ›„์† ์—˜๋ฆฌ๋จผํŠธ๋กœ <span> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dummyTweets์˜ ํŠธ์œ— ์ƒ์„ฑ ์ผ์ž๋ฅผ <span>์˜ ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๋กœ ๋„ฃ์Šต๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ์ด๋ฆ„์€ tweet__createdAt์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠธ์œ— ์ƒ์„ฑ ์ผ์ž๋Š” yyyy. m. d. ํ˜•์‹์œผ๋กœ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (โ€™static/dummyTweets.jsโ€™ ํŒŒ์ผ์„ ์ž˜ ์ฝ์–ด๋ณด์„ธ์š”.)
<div className="tweet__content">
            .
            .
            .
                {/* TODO : ํŠธ์œ— ์ƒ์„ฑ ์ผ์ž๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. */}
                <span className='tweet__createdAt'>{tweet.createdAt}</span>
              </div>
            .
            .
            .

Q : ํŠธ์œ— ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • li.tweet ์—˜๋ฆฌ๋จผํŠธ์˜ ํ›„์† ์—˜๋ฆฌ๋จผํŠธ๋กœ <div> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dummyTweets์˜ ํŠธ์œ— ๋‚ด์šฉ์„ <div> ์˜ ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๋กœ ๋„ฃ์Šต๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ์ด๋ฆ„์€ tweet__message์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
<div className="tweet__content">
              <div className="tweet__userInfo">
                .
                .
                .
              </div>
              <div className='tweet__message'>{tweet.content}</div>
            </div>

Q : Feature ์ปดํฌ๋„ŒํŠธ์˜ ํ›„์† ์ปดํฌ๋„ŒํŠธ๋กœ Counter ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Q : Features ์ปดํฌ๋„ŒํŠธ์˜ ํ›„์† ์ปดํฌ๋„ŒํŠธ๋กœ Footer ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const Features = () => {
  return (
    <section className="features">
      <div className="tweetForm__container">
        <div className="tweetForm__wrapper">
          <div className="tweetForm__profile"></div>
          <Counter /> // Feature์˜ ํ›„์† Counter ์ปดํฌ๋„ŒํŠธ ์ง€์ •
        </div>
      </div>
      <Tweets />  
      <Footer /> // Feature์˜ ํ›„์† Footer ์ปดํฌ๋„ŒํŠธ ์ง€์ •
    </section>
  );
};

Q : App ์ปดํฌ๋„ŒํŠธ์˜ ํ›„์† ์ปดํฌ๋„ŒํŠธ๋กœ Sidebar ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const App = () => {
  return (
    <div className="App">
      <main>
        {/* TODO : Sidebar ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. */}
        <Sidebar /> // App ํ›„์† Sidebar ์ปดํฌ๋„ŒํŠธ ์ง€์ •
        <Features />
      </main>
    </div>
  );
};

Q : ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์„ ํ™œ์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ํŠธ์œ— ์ค‘ ์œ ์ € ์ด๋ฆ„์ด parkhacker์ธ ๋ฐฐ๊ฒฝ์ƒ‰์ด var(--point-color-tint-2)๊ฐ€ ๋˜๋„๋ก ํด๋ž˜์Šค(tweet__username--purple)๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (tweet__username tweet__username--purple)

  • โ€˜src/App.cssโ€™์— ํด๋ž˜์Šค๊ฐ€ ๋ฏธ๋ฆฌ ์ค€๋น„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. (className : 'tweet__username--purple')
const Tweets = () => {
  return (
    <ul className="tweets">
      {dummyTweets.map((tweet) => {
        const isParkHacker = tweet.username === 'parkhacker';  // ๋ณ€์ˆ˜ isParkHacker = ๋ฐ•ํ•ด์ปค

        const tweetUserNameClass = isParkHacker
                ? 'tweet__username tweet__username--purple'   
                : 'tweet__username';
          // ์‚ผํ•ญ์—ฐ์‚ฐ์ž์ด์šฉํ•˜์—ฌ ๋ฐ•ํ•ด์ปค๋ผ๋ฉด ๋ณด๋ผ์ƒ‰์œผ๋กœ ๋œจ๊ฒŒํ•˜๋ผ.
                
        return (
          <li className="tweet" key={tweet.id}>
            <div className="tweet__profile">
              <img src = {tweet.picture}></img>
            </div>
            <div className="tweet__content">
              <div className="tweet__userInfo">
                {/* TODO : ์œ ์ ธ ์ด๋ฆ„์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. */}
                <span className={tweetUserNameClass}>{tweet.username}</span> 
                // ์œ„์— ์„ ์–ธํ–ˆ๋˜ tweetUserNameClass
              </div>

profile
๊ฐœ๋ฐœ์ž ์„ฑ์žฅ ๊ณ„๋‹จ ์˜ฌ๋ผ๊ฐ€๊ธฐ

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