React | ๐Ÿฑ CATstagram ๊ธฐ์ˆ  ํšŒ๊ณ  ๋ฐ ๋งˆ๋ฌด๋ฆฌ

๋ฏธ์—ฐยท2021๋…„ 10์›” 3์ผ
4

CATstagram

๋ชฉ๋ก ๋ณด๊ธฐ
1/1
post-thumbnail

๐Ÿฑ ๊ธฐ์ˆ  : React, scss, jsx

๐Ÿฑ ๊ธฐ๊ฐ„ : 2021/09/13 ~ 2021/10/01

๐Ÿฑ ๋ฐ”๋‹๋ผ JS๋กœ ํด๋ก ํ–ˆ๋˜ ๋‚˜์˜ ์บฃ์Šคํƒ€๊ทธ๋žจ์„ ๋ฆฌ์•กํŠธ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์—์„œ ๊ธฐ์ˆ ์ ์œผ๋กœ ๋ง‰ํžˆ๊ฑฐ๋‚˜ ํ˜ผ์ž ๋งŽ์ด ๊ณ ๋ฏผํ•˜๊ณ , ๋˜ํ•œ ์ธ์ƒ ๊นŠ์—ˆ๋˜ ์ฝ”๋“œ๋“ค์„ ๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์–ด์„œ ํฌ์ŠคํŒ…์œผ๋กœ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค.


Login.js

1. ๊ณ„์‚ฐ๋œ ์†์„ฑ๋ช…์„ ์ด์šฉํ•œ inputHandler ๋ฉ”์„œ๋“œ ํ•ฉ์น˜๊ธฐ

handleIdInput ์™€ handlePwInput ๋ฉ”์„œ๋“œ๋Š”, ์•„์ด๋”” <input>๊ณผ ํŒจ์Šค์›Œ๋“œ <input>์— ์ž…๋ ฅํ•œ ํ…์ŠคํŠธ๋ฅผ ๊ฐ๊ฐ ํ•ด๋‹นํ•˜๋Š” state์— ์ €์žฅํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

// ๊ธฐ์กด ์ฝ”๋“œ
  handleIdInput = e => {
    this.setState({
      idValue: e.target.value,
    });
  };

  handlePwInput = e => {
    this.setState({
      pwValue: e.target.value,
    });
  };

<input id="idInput" placeholder="์ „ํ™”๋ฒˆํ˜ธ, ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋˜๋Š” ์ด๋ฉ”์ผ"
  	onChange={this.handleIdInput} />

<input type="password" id="pwInput" placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ"
  	onChange={this.handlePwInput} />

์ด๋ฒคํŠธ ๊ฐ์ฒด e์˜ ์ถœ์ฒ˜๊ฐ€ ๊ฐ๊ฐ์˜ <input>๋งˆ๋‹ค ๋‹ค๋ฅด๊ณ , ์ €์žฅํ•ด์•ผ ํ•  state๊ฐ€ ๋‹ค๋ฅผ ๋ฟ. ๋ฉ”์„œ๋“œ์˜ ํ˜•ํƒœ๋Š” ๋น„์Šทํ•˜๋‹ค. ์ด๋ฅผ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋กœ ํ•ฉ์น  ๋ฐฉ๋ฒ•์€ ์—†๋Š”์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ๊ธธ๊ฒŒ ํ–ˆ์—ˆ๋‹ค.

์‚ฌ์‹ค ์ด๋•Œ๋Š” ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃฌ ์ง€ ์–ผ๋งˆ ์•ˆ ๋˜์—ˆ์„ ๋•Œ๋ผ, ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฏธ์ˆ™ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ค‘๋ณต๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ•ฉ์น˜๋ ค๊ณ  ํ–ˆ์—ˆ๋‹ค. (์‹œ๊ฐ„์ด ์‹ค์ œ๋กœ ์˜ค๋ž˜ ์ง€์ฒด๋˜๊ธฐ๋„ ํ–ˆ์—ˆ๋‹ค.)

// ์‹œ๋„ํ–ˆ๋˜ ์ฝ”๋“œ
  handleInput = e => {
    this.setState({
      IdValue: e.target.value,
      pwValue: e.target.value,
    });
  };

<input id="idInput" placeholder="์ „ํ™”๋ฒˆํ˜ธ, ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋˜๋Š” ์ด๋ฉ”์ผ"
  	onChange={this.handleInput} />

<input type="password" id="pwInput" placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ"
  	onChange={this.handleInput} />
  • ์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•˜๋ฉด, ์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ์ถœ์ฒ˜์ธ <input>์€ ๋‹ค๋ฅธ๋ฐ, ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค. ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด ์•„์ด๋”” <input>์— ์ž…๋ ฅํ–ˆ๋˜ ์ž…๋ ฅ๊ฐ’์ด IdValue์—๋„, pwValue์—๋„ ์ €์žฅ์ด ๋œ๋‹ค๋Š” ์ ์„ ๊นจ๋‹ฌ์•˜๋‹ค.
  • event.target์€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์†์„ฑ์„ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š”, <input> ํƒœ๊ทธ ์•ˆ์— name ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ input handler๋ฅผ ํ•ฉ์น˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ๋‹ค.
// ๋ฆฌํŒฉํ† ๋ง ํ›„์˜ ์ฝ”๋“œ
  construct() {
    super();
    this.state= {
      email: '',
      password: '',
    }
  }

  handleInput = e => {
    const { name, value } = e.target;
    this.setState({
      [name] : value;
    });
  };

<input id="idInput" name="email" placeholder="์ „ํ™”๋ฒˆํ˜ธ, ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋˜๋Š” ์ด๋ฉ”์ผ"
  	onChange={this.handleInput} />

<input type="password" id="password" name="pwName" placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ"
  	onChange={this.handleInput} />
  1. state๋ช…์€ ๊ฐ <input>์˜ name๊ณผ ๋˜‘๊ฐ™์ด ์„ค์ •. (๊ณ„์‚ฐ๋œ ์†์„ฑ๋ช…!)
  2. handleInput ๋ฉ”์„œ๋“œ์— <input>์˜ name ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ๊ฐ๊ฐ ๋‹ค๋ฅธ <input>๋งˆ๋‹ค state ๊ฐ’์„ ์ €์žฅ์‹œ์ผœ ์ค„ ์ˆ˜ ์žˆ๋‹ค.
// ๊ธฐ์กด ์ฝ”๋“œ - ์ด๋™ํ•  ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด ๊ฒฝ๋กœ ๋ฏธ์ง€์ •
 <a href="#" className="pwForgot">
	๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์žŠ์œผ์…จ๋‚˜์š”?
 </a>
  • <a> ๋Š” ์ƒˆ๋กœ๊ณ ์นจ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ html ํŽ˜์ด์ง€ ๋ฌธ์„œ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ๋ฐ›์•„์˜ค๊ฒŒ ๋˜๋ฉฐ, ๋˜‘๊ฐ™์€ ๋ถ€๋ถ„์„ ๋ถˆ๋Ÿฌ์˜ค๋”๋ผ๋„ ๋‹ค์‹œ ํŒŒ์‹ฑํ•ด์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ๋ฉด์œผ๋กœ๋„ ์ข‹์ง€๊ฐ€ ์•Š๊ณ , ์ž์›์ ์œผ๋กœ ๋‚ญ๋น„๊ฐ€ ๋œ๋‹ค.
  • ํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ๋Š” SPA์ด๋‹ค. ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€ ์•ˆ์—์„œ ์ด๋™ํ•ด์•ผ ํ•  ๋‹ค๋ฅธ ํŽ˜์ด์ง€(=์ปดํฌ๋„ŒํŠธ)๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ˜•์‹์ด๋‹ค.
  • <Link>๋Š” ๋˜‘๊ฐ™์€ ๋ถ€๋ถ„์„ ๋‹ค์‹œ ํŒŒ์‹ฑํ•˜์ง€ ์•Š๊ณ , ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ปดํฌ๋„ŒํŠธ๋งŒ ํ˜ธ์ถœํ•ด ์ฃผ๋ฏ€๋กœ ๋ Œ๋”๋ง ์ตœ์ ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.
// ๋ฆฌํŒฉํ† ๋ง ํ›„์˜ ์ฝ”๋“œ
// Link import๋ฌธ ์„ค์ •
import { Link } from 'react-router-dom';

// ์ด๋™ํ•  ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด ๊ฒฝ๋กœ ๋ฏธ์ง€์ •
 <Link to="#" className="pwForgot">
	๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์žŠ์œผ์…จ๋‚˜์š”?
 </Link>

3. className์˜ ๋™์  ์‚ฌ์šฉ

  • style์— ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ๋กœ ์ธํ•ด ๋ณ€ํ™”๋ฅผ ์ค„ ๋•Œ, inline์œผ๋กœ ๋ฐ”๋กœ ์ค„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์ง€์–‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

    ๐Ÿ’ก ์™œ ์ง€์–‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊นŒ?
    ์šฐ์„  style ์†์„ฑ์ด ๊ธธ์–ด์ง„๋‹ค๋ฉด ๊ฐ€๋…์„ฑ์ด ์ข‹์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ๋˜ํ•œ html ํƒœ๊ทธ ์•ˆ์— ์ธ๋ผ์ธ style๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์€ css ํŒŒ์ผ ์ ์šฉ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ์—, ํŒŒ์‹ฑ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

// ๋ฆฌํŒฉํ† ๋ง ํ›„์˜ ์ฝ”๋“œ
constructor() {
    super();
    this.state = {
      email: '',
      password: '',
      buttonColor: false,
    };
  }

  buttonColorChange = () => {
    const { idValue, pwValue } = this.state;
    const isButtonActive = email.includes('@') && password.length >= 5;
    this.setState({ buttonColor: isButtonActive });
  };

<button className={buttonColor ? 'loginOn' : 'loginOff'}> ๋กœ๊ทธ์ธ </button>
  • scss ํŒŒ์ผ๊ณผ ํ•จ๊ป˜, className ๋™์  ์‚ฌ์šฉ์„ ํ™œ์šฉํ•ด ๋ณด๋„๋ก ํ•˜์ž.
  • loginOn : ํ™œ์„ฑํ™”๋œ ์ง„ํ•œ ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ / loginOff : ๋น„ํ™œ์„ฑํ™”๋œ ์—ฐํ•œ ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ

์˜ˆ์‹œ 1 ) ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ์ƒ‰์ƒ ํ™œ์„ฑํ™”

์˜ˆ์‹œ 2 ) ๋ฉ”์ธ ์ƒ๋‹จ๋ฐ” ํ”„๋กœํ•„ ํด๋ฆญ์‹œ ํŒ์—… On/Off

์˜ˆ์‹œ 3 ) ์ข‹์•„์š” ํ•˜ํŠธ ํด๋ฆญ


scss

4. reset.scss & common.scss

  • reset.scss & common.scss๋Š” ๊ณตํ†ต์œผ๋กœ ์“ฐ์ด๋Š” scss ํŒŒ์ผ์ด๋ฏ€๋กœ, ๊ณตํ†ต ํŽ˜์ด์ง€์ธ index.js์—์„œ ํ•œ ๋ฒˆ๋งŒ importํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์ดˆ๊ธฐํ™” ํ•˜๋Š” ์„ธํŒ…์€ reset.scss์—, ๋ชจ๋‘๊ฐ€ ๊ฐ™์ด ์“ธ ์ˆ˜ ์žˆ๋Š” css๋Š” common.scss์— ๋„ฃ์ž.
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

5. Sass nesting

  • nesting ์„ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š”, ๋ฆฌ์•กํŠธ๊ฐ€ SPA์ธ ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค.
  • ๊ฒฐ๊ตญ์—๋Š” ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์ง€๋Š” ํŒŒ์ผ๋“ค์ด๋ผ, ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์žˆ๋Š” ์š”์†Œ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ํด๋ž˜์Šค๋ช…์— ๋”ฐ๋ผ UI ๊ตฌ์กฐ๊ฐ€ ๋ญ‰๊ฐœ์ง€์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” css์—์„œ sass๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ nesting์„ ๊ผญ ํ•˜๋„๋ก ํ•˜์ž.

main.js

6. import ์ˆœ์„œ

import { Component } from 'react';
import CenterBar from './components/topUserSearch/CenterBar';
import MainFeed from './components/mainFeed/MainFeed';
import SideBar from './components/sideBar/SideBar';
import './Main.scss';
  1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ : ๋ฆฌ์•กํŠธ ๊ด€๋ จ ํŒจํ‚ค์ง€, ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  2. ์ปดํฌ๋„ŒํŠธ : ๊ฐ€๊นŒ์šด ์ปดํฌ๋„ŒํŠธ to ๋จผ ์ปดํฌ๋„ŒํŠธ
  3. ํ•จ์ˆ˜, ๋ณ€์ˆ˜ ๋ฐ ์„ค์ • ํŒŒ์ผ
  4. ์‚ฌ์ง„ ๋“ฑ ๋ฏธ๋””์–ด ํŒŒ์ผ (.png)
  5. css ํŒŒ์ผ (.scss)

7. JSON ํŒŒ์ผ์˜ Mock Data ํ˜ธ์ถœ

  1. ๊ฑฐ์ง“๋œ, ๊ฐ€์งœ์˜, ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ.
  2. ๋ฐฑ์—”๋“œ API๋ฅผ ๋ชจ๋ฐฉํ•œ ๋ฐ์ดํ„ฐ.
  • ๋ฐฑ์—”๋“œ์—์„œ API๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ผ ๋•Œ, ๋ฐฑ์—”๋“œ API๊ฐ€ ์™„์„ฑ์ด ๋˜์ง€ ์•Š์•˜์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐฑ์—”๋“œ๊ฐ€ API๋ฅผ ์™„์„ฑํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๊ฐ€์งœ์˜ ๋ฐ์ดํ„ฐ์ธ Mock Data๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ ์ƒํ™ฉ์„ ๋ฏธ๋ฆฌ ๋Œ€๋น„ํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๋ฐ์ดํ„ฐ์— ๋งž๊ฒŒ UI๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ๊ตฌํ˜„๋˜๋Š”์ง€ ๋จผ์ € ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
  • ๋˜ํ•œ Mock Data๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ ๋ฐฑ์—”๋“œ API์—์„œ ๋ณด๋‚ด์ฃผ๋Š” response๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ์ธ์ง€, key-Value๊ฐ’์„ ๋ฏธ๋ฆฌ ํ™•์ธํ•˜๊ณ  ๋งž์ถฐ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ์ถ”ํ›„ ์‹ค์ œ ๋ฐฑ์—”๋“œ API๋ฅผ ์ˆ˜์›”ํ•˜๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  constructor() {
    super();
    this.state = {
      profileLayer: false,
      feedInfo: [],
    };
  }

  componentDidMount() {
    fetch('http://localhost:3000/miyeon/data/mainFeed.json', { method: 'GET' })
      .then(res => res.json())
      .then(data =>
        this.setState({
          feedInfo: data,
        })
      );
  }
  1. componentDidMount() : ์ปดํฌ๋„ŒํŠธ๊ฐ€ mount ๋˜๋Š” ์‹œ์ ์— ์ƒ์„ฑ๋˜๋Š” ๋ผ์ดํ”„์‚ฌ์ดํด ๋ฉ”์„œ๋“œ์ด๋‹ค. ์ด ์‹œ์ ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ํ•œ๋‹ค.
  2. json ํŒŒ์ผ์€ public ํด๋” > data ํด๋” ์•ˆ์— ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค. public ํด๋”๋Š” ์‹ค์ œ ๋ฐฐํฌ ํ›„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํด๋”์ด๋ฏ€๋กœ, Mock Data์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ์—ญ์‹œ public ํด๋” ์•ˆ์— json ํŒŒ์ผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.
  3. javascript์—์„œ http ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋Š” fetch ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” http ์š”์ฒญ์„ ๋ณด๋‚ผ API ์ฃผ์†Œ, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ์˜ ์˜ต์…˜์„ ๋„ฃ๋Š”๋‹ค.
  4. .then(res => res.json()) : res๋Š” http ํ†ต์‹  ์š”์ฒญ/์‘๋‹ต ์ค‘ ์‘๋‹ต์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” response object์ด๋‹ค. ์‘๋‹ต์œผ๋กœ ๋ฐ›๋Š” JSON ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” json() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  return ํ•ด์•ผ ํ•œ๋‹ค.
  5. .then(data => this.setState({ feedInfo: data, })); : json ํŒŒ์ผ์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋“ค์€ ๋ฐฐ์—ด์˜ ํ˜•ํƒœ์ด๋ฏ€๋กœ, ๋ฐฐ์—ด state์ธ feedInfo์— ๋ฎ์–ด์”Œ์šด๋‹ค.

json ํŒŒ์ผ๋กœ ๋ถˆ๋Ÿฌ์˜จ ๊ฐ์ฒด๋“ค์€, main.js์— state ๋ฐฐ์—ด๋กœ ์ €์žฅ์ด ๋˜์—ˆ๋‹ค.
๐Ÿ’ก ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์„ ์›ํ•  ๋•Œ json ํŒŒ์ผ ๋‚ด๋ถ€์— ์žˆ๋Š” ๊ฐ์ฒด๋“ค์€ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€ํ•˜์ง€๋งŒ, main.js์˜ state์—์„œ ์ˆ˜์ • ๋ฐ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

8. .map() ๋ฉ”์„œ๋“œ๋กœ ๋ฐ˜๋ณต๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ฟŒ๋ฆฌ๊ธฐ

์บฃ์Šคํƒ€๊ทธ๋žจ์˜ ํ•˜๋‚˜์”ฉ์˜ ํ”ผ๋“œ๋ฅผ ๋‹ด๋Š” <article>๋ฅผ ์ปดํฌ๋„ŒํŠธํ™” ํ•ด์ฃผ์—ˆ๋‹ค.
mainFeed.json์— ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ํ”ผ๋“œ์˜ ์ •๋ณด๋ฅผ ๋ช‡ ๊ฐœ์”ฉ ๋‹ด์•„ ์ฃผ์—ˆ๊ณ , ์ด๋ฅผ state ๊ฐ’์œผ๋กœ ๋ฐ›์•˜์œผ๋‹ˆ ๋ฐ˜๋ณต๋˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋ฅผ .map() ๋ฉ”์„œ๋“œ๋กœ ๋ฟŒ๋ ค ๋ณด์•˜๋‹ค.

<div>
{this.state.feedInfo.map(user => {
   return (
    <MainFeed userData={user}
              key={user.no} />
           ); 
 })}
</div>
  • fetch ํ•จ์ˆ˜๋กœ ๋ฐ›์€ Mock data๋Š” ๋ฐฐ์—ด state์ธ feedInfo์— ์ €์žฅํ–ˆ๋‹ค.
  • ์ด ๋ฐฐ์—ด์„ .map() ๋ฉ”์„œ๋“œ๋กœ ํ”ผ๋“œ ์ปดํฌ๋„ŒํŠธ ํ•˜๋‚˜์”ฉ ๋ฟŒ๋ ค ์ค„ ๊ฒƒ์ด๋‹ค.
  • user ์š”์†Œ๋ฅผ props์ธ userData๋กœ ์ „๋‹ฌํ–ˆ๋‹ค.
  • key๋Š” ๋ฌด์กฐ๊ฑด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹Œ, ๋ฟŒ๋ ค์ค„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ช…์‹œํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์„ ์–ธํ•˜์ž. key๋ฅผ ์ธ๋ฑ์Šค๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ๋„ ์ง€์–‘ํ•ด์•ผ ํ•œ๋‹ค.
    ๐Ÿ’ก ๋‚˜์ค‘์— ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋œ๋‹ค๋ฉด ์ธ๋ฑ์Šค ๊ฐ’์— ๋ณ€๊ฒฝ์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

9. ํ”ผ๋“œ ๋Œ“๊ธ€ ์—…๋กœ๋“œ

  • ๋Œ“๊ธ€ ๋ชฉ๋ก์€ comment.js๋กœ ์ปดํฌ๋„ŒํŠธํ™” ํ•ด์ฃผ์—ˆ๊ณ , ์—…๋กœ๋“œ ๋  ๋Œ“๊ธ€ ํ•œ ์ค„์€ uploadComment.js๋กœ ์ปดํฌ๋„ŒํŠธํ™” ํ•ด์ฃผ์—ˆ๋‹ค.
constructor() {
    super();
    this.state = {
      inputVal: '',  	// Input์— ์ž…๋ ฅ๋˜๋Š” ํ…์ŠคํŠธ๋ฅผ ๋ฐ›์„ ์šฉ๋„
      commentList: [],  // ์—…๋กœ๋“œ ๋  ๋Œ“๊ธ€์„ ๋ฐ›์„ ๋ฐฐ์—ด
    };
  }

// ๋Œ“๊ธ€ ์—…๋กœ๋“œ ๋ฉ”์„œ๋“œ
addMyComment = e => {
    e.preventDefault();
    const { commentList, inputValue } = this.state;
    const newArr = [
      ...commentList,
      {
        id: commentList.length + 1,
        name: 'buzzi_nyang',
        content: inputValue,
      }, // ๋Œ“๊ธ€ ํ•˜๋‚˜ ์—…๋กœ๋“œ ์‹œ ์ถ”๊ฐ€๋  ๋Œ“๊ธ€์˜ ์ •๋ณด๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ›๋Š”๋‹ค.
    ];
    this.setState({
      commentList: newArr,
      inputValue: '', // input์ฐฝ ํ…์ŠคํŠธ ์ดˆ๊ธฐํ™”
    });
  };
  1. e.preventDefault(); : ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๋‚˜๋ฉด ํŽ˜์ด์ง€๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋ฏ€๋กœ, ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰์•„์ฃผ๊ณ ์ž ์ผ๋‹ค.

  2. ...commentList : commentList์— ๋‹ด๊ฒจ์žˆ๋˜ ์š”์†Œ๋“ค์„ ๋ณต์ œํ•ด์˜จ๋‹ค.

    ๐Ÿ’ก Three dot ํ‘œ๊ธฐ๋ฒ• : ๋ฐฐ์—ด์—์„œ ์“ฐ์ผ์‹œ, ๋ฐฐ์—ด1์˜ ์š”์†Œ๋“ค์„ ๋ฐฐ์—ด2์— ํ•˜๋‚˜์”ฉ ๋ถ„ํฌ๋˜์–ด ๊ณ ๋ฅด๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„๋•Œ ...๋ฐฐ์—ด1 ๊ณผ ๊ฐ™์ด ์“ฐ์ธ๋‹ค. ์  ์„ธ๊ฐœ๋กœ ์ƒ๋žตํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. Array.concat() ๋ฉ”์„œ๋“œ์™€ ์“ฐ์ž„์ด ๋น„์Šทํ•˜๋‹ค.

  3. ๋Œ“๊ธ€ ํ•˜๋‚˜ ์—…๋กœ๋“œ ์‹œ ์ถ”๊ฐ€๋  ๋Œ“๊ธ€์˜ ์ •๋ณด๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ›๊ณ , ์ƒˆ๋กœ์šด ๋ฐฐ์—ด newArr๋ฅผ ์„ ์–ธํ•˜์—ฌ newArr์— ์ด๋“ค์„ ๋‹ด๋Š”๋‹ค.

    • id: commentList.length + 1 -> commentList ๋ฐฐ์—ด์˜ ์ด ๊ธธ์ด์—๋‹ค 1์„ ๋”ํ•ด์•ผ ํ˜„์žฌ ๋Œ“๊ธ€์ด ๋ช‡ ๋ฒˆ์งธ ์š”์†Œ์— ์žˆ๋Š”์ง€ ์นด์šดํŠธ ๋œ๋‹ค.
    • name: 'buzzi_nyang' -> ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ์ด ๊ณ„์ •์ฃผ์ธ์ด๋ฏ€๋กœ.. ์ผ๋‹จ ๊ณ„์ •์ฃผ ๊ณ„์ • ๋ฐ•์ œ.
    • content: e.target.value -> input์— ์ž…๋ ฅํ•˜๋Š” ๋Œ“๊ธ€์„ content์— ์ €์žฅํ•œ๋‹ค.
  4. 3๋ฒˆ์—์„œ ์ €์žฅํ–ˆ๋˜ ๋Œ“๊ธ€์˜ ์ •๋ณด ๋ฐฐ์—ด newArr๋ฅผ ๊ธฐ์กด ๋ฐฐ์—ด commentList ์— ๋ฎ์–ด์”Œ์šด๋‹ค.

    ๋ฎ์–ด ์”Œ์šฐ๋Š” ๋ฐฉ๋ฒ• ๋ง๊ณ , ํ˜„์žฌ ์—…๋กœ๋“œ๋  ๋Œ“๊ธ€ ๊ฐ์ฒด ํ•˜๋‚˜๋งŒ์„ ๊ธฐ์กด ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†๋Š”์ง€. ๊ธฐ์กด ๋ฐฐ์—ด์— ๋Œ“๊ธ€ ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ ๋Œ“๊ธ€ ๋ฐ์ดํ„ฐ๋“ค์ด ์†์ƒ๋  ๋ฐฉ๋ฒ•์€ ์—†๋Š”์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•˜์˜€๋‹ค. ํ•ด๋‹น ๋Œ“๊ธ€ ๊ฐ์ฒด๋ฅผ []๋กœ ๋ฌถ์–ด ๋ฐฐ์—ดํ™” ํ•˜์—ฌ, commentList.push([ํ•ด๋‹น๋Œ“๊ธ€๊ฐ์ฒด]) ๋กœ ํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?

  5. ํŠนํžˆ input์ฐฝ์— ์ž…๋ ฅ๋œ ํ…์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์• ๋ฅผ ๋งŽ์ด ๋จน์—ˆ๋‹ค. ๋Œ“๊ธ€์„ ์—…๋กœ๋“œํ•œ ๋’ค์—, ๋Œ“๊ธ€ ์ž…๋ ฅ์ฐฝ <input>์— ์˜ฌ๋ ธ๋˜ ๋Œ“๊ธ€ ๋ฌธ์ž์—ด์ด ๋‹ค ์ดˆ๊ธฐํ™”๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ์•„๋ž˜ ์ฝ”๋“œ๋กœ๋Š” ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์ง€ ์•Š๊ณ  ๋ฌธ์ž์—ด์ด ๊ทธ๋Œ€๋กœ ๋‚จ์•„ ์žˆ์—ˆ๋˜ ๊ฒƒ์ด๋‹ค.

// ๊ธฐ์กด ์ฝ”๋“œ
 this.setState({
      commentList: newArr,
      inputValue: '', // input์ฐฝ ํ…์ŠคํŠธ ์ดˆ๊ธฐํ™”
    });
  • console.log(inputValue)๋ฅผ ์ฐ์–ด ๋ณด๋ฉด ๋นˆ ๋ฌธ์ž์—ด์ด ๋‚˜์˜ค๊ธด ํ•˜๋Š”๋ฐ, <input>์˜ ๋ฌธ์ž์—ด์€ ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์ง€ ์•Š๊ธธ๋ž˜ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •์„ ํ–ˆ์—ˆ๋‹ค.
// ์ˆ˜์ •ํ•œ ์ฝ”๋“œ
 this.setState({
      commentList: newArr,
      inputValue: '', // input์ฐฝ ํ…์ŠคํŠธ ์ดˆ๊ธฐํ™”
    });

  let length = document.getElementsByClassName('.wrapper').length;
  e.target[length].value = '';
  • DOM ์ด๋ฒคํŠธ ํƒœ๊ทธ๋กœ ์ „์ฒด ํ”ผ๋“œ <article> ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ด์„œ, ํ˜„์žฌ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๊ณ  ์žˆ๋Š” ์š”์†Œ์˜ value ๊ฐ’์„ ๋นˆ๊ฐ’์œผ๋กœ ์„ค์ •ํ–ˆ๋”๋‹ˆ <input>์˜ ๋ฌธ์ž์—ด์ด ์ดˆ๊ธฐํ™”๋˜์—ˆ์—ˆ๋‹ค.
  • ํ”ผ๋“œ๋ฐฑ ๋ฐ›์€ ๋ฌธ์ œ์ ์€ DOM ์ด๋ฒคํŠธ ํƒœ๊ทธ ์ž์ฒด๋Š” ๋ฆฌ์•กํŠธ์—์„œ ์ง€์–‘ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์œผ๋ฉฐ, ๋Œ€์‹  Ref ๋ผ๋Š” ๊ฒƒ์„ ์“ธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

    ๐Ÿ’ก Ref? : ๋ฆฌ์•กํŠธ์—์„œ state๋กœ๋งŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๊ณ , DOM์„ ๋ฐ˜๋“œ์‹œ ์ง์ ‘ ๊ฑด๋“œ๋ ค์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. HTML์„ ์ž‘์„ฑํ•  ๋•Œ ํƒœ๊ทธ์— id๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๋ฆฌ์•กํŠธ์—์„œ๋„ DOM์— ์ด๋ฆ„์„ ๋‹ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • ๋˜ํ•œ ๋‚˜์ค‘์— .wrapper ํด๋ž˜์Šค๋ช…์„ ๊ฐ€์ง„ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๊ฐ€ ๋œ๋‹ค๋ฉด UI๊ฐ€ ๋ง๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด, ์ด ๋ฐฉ๋ฒ•์€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์•˜๋‹ค. ๋”ฐ๋ผ์„œ ์ˆ˜์ •ํ•œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
// ๋ฆฌํŒฉํ† ๋ง ํ›„ ์ฝ”๋“œ
 this.setState({
      commentList: newArr,
      inputValue: '', // input์ฐฝ ํ…์ŠคํŠธ ์ดˆ๊ธฐํ™”
    });

  handleInput = e => {
    this.setState({
      inputValue: e.target.value,
    });
  };

<input className="comment"
       placeholder="๋Œ“๊ธ€ ๋‹ฌ๊ธฐ..."
       value={inputValue}
       onChange={this.handleInput} />
  • <input>์— value ์†์„ฑ์„ ๋ถ€์—ฌํ•˜๊ณ , ์ž…๋ ฅ๋ฐ›๋Š” state์ธ this.state.inputValue๋ฅผ ๊ทธ๋Œ€๋กœ ์จ์ฃผ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด <input>์˜ value๋Š” ์ž…๋ ฅํ•˜๋Š” ๋Œ€๋กœ ์จ์งˆ ํ…Œ๊ณ , state์ธ inputValue์—๋„ ๊ทธ๋Œ€๋กœ ์ €์žฅ์ด ๋  ํ…Œ๊ณ , ๋Œ“๊ธ€์ด ์—…๋กœ๋“œ ๋œ๋‹ค๋ฉด <input>์˜ ๋ฌธ์ž์—ด๋„ ์ดˆ๊ธฐํ™” ๋  ๊ฒƒ์ด๋‹ค.

10. ํŠน์ • ๋Œ“๊ธ€ ์‚ญ์ œ ๊ธฐ๋Šฅ

.filter() ๋ฉ”์„œ๋“œ๋ฅผ ์ฒ˜์Œ ์จ ๋ณด์•˜๋‹ค. ์ ์‘ํ•˜๋Š” ๋ฐ๊นŒ์ง€ ์ดํ‹€์€ ๊ฑธ๋ ธ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

// ๋Œ“๊ธ€ ์‚ญ์ œ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€
<img src="./images/miyeon/trash.png"
     onClick={() => this.props.deleteComment(comment.id)}
     alt="deleteComment" />
  1. ์‚ญ์ œ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€์— onClick ์ด๋ฒคํŠธ๋ฅผ ์ฃผ์—ˆ๊ณ , ๋ช‡ ๋ฒˆ์งธ ๋Œ“๊ธ€ id์ธ์ง€ ์•Œ๋ ค์ฃผ๋Š” ํ•ด๋‹น id ์š”์†Œ๊นŒ์ง€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ์žˆ๋Š” ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜์˜€๋‹ค.
// ๋Œ“๊ธ€ ์‚ญ์ œ ๋ฉ”์„œ๋“œ
  uploadDeleteComment = id => {
    const deleteMyComment = this.state.commentList.filter(
      comment => comment.id !== id
    );
    this.setState({
      commentList: deleteMyComment,
    });
  };
  1. ์—…๋กœ๋“œ ๋œ ๋Œ“๊ธ€ ๋ฐฐ์—ด์ธ commentList์— filter ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๋‹ค.
  2. ๋Œ“๊ธ€ ์š”์†Œ ํ•˜๋‚˜์˜ id๊ฐ€, ํด๋ฆญํ•œ ํ•ด๋‹น ์š”์†Œ์˜ id๊ฐ€ ๊ฐ™์ง€ ์•Š์œผ๋ฉด ์กฐ๊ฑด์‹์ด ์„ฑ๋ฆฝํ•œ๋‹ค. ๋งŒ์•ฝ id๊ฐ€ ์„œ๋กœ ๊ฐ™๋‹ค๋ฉด false๋กœ, ๋ฐฐ์—ด์—์„œ ๋น ์ง€๊ฒŒ ๋˜์–ด ๋Œ“๊ธ€ ์‚ญ์ œ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ฒƒ์ด๋‹ค.

    ์„ ํƒํ•˜์ง€ ์•Š์€ ๋Œ“๊ธ€ ์š”์†Œ๋Š” true๋กœ, ์ด๋“ค๋งŒ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง„๋‹ค. ์„ ํƒํ•œ ๋Œ“๊ธ€ ์š”์†Œ๋Š” ์‚ญ์ œํ•  ๋Œ“๊ธ€ ์š”์†Œ์ด๋‹ˆ๊นŒ, ํ•ด๋‹น ์กฐ๊ฑด์‹์ด ์„ฑ๋ฆฝ์ด ๋˜์ง€ ์•Š์•„ false๋กœ ๋˜๋ฉฐ, ๊ธฐ์กด ๋ฐฐ์—ด์—์„œ ๋น ์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

11. ์ƒ๋‹จ๋ฐ” ์œ ์ € ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ

.filter() ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์‹ค ์•„์ง๊นŒ์ง€๋„ ๋‚ฏ์„ค๋‹ค.

<div className={this.state.searchLayer ? 'searchOn' : 'searchOff'}>
          <ul className="searchUsersul">
            {this.state.users
              .filter(people => {
                if (this.state.searchKeyword === '') {
                  return people;
                } else if (
                  people.id.toLowerCase().includes(this.state.searchKeyword.toLowerCase())
                ) {
                  return people;
                }
              })
              .map(userArr => {
                return <NavUserSearch usersInfo={userArr} key={userArr.no} />;
              })}
          </ul>
        </div>
  1. ๊ฒ€์ƒ‰์ฐฝ์€ ๊ฒ€์ƒ‰ <input> ์„ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ํด๋ž˜์Šค๋ช… ๋ณ€๊ฒฝ์œผ๋กœ On/Off ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ๋‹ค.
  2. ์œ ์ € ๋ชฉ๋ก์ด ๋“ค์–ด์žˆ๋Š” ๋ฐฐ์—ด users์— ๋Œ€ํ•ด .filter ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๋‹ค.
  3. if (this.state.searchKeyword === '') return peopleArr;
    • ๊ฒ€์ƒ‰ <input>์— ์•„๋ฌด๊ฒƒ๋„ ์ž…๋ ฅํ•˜์ง€ ์•Š์•˜์„ ๋•Œ, ๋ชจ๋“  ์œ ์ € ๋ชฉ๋ก์„ ๋ณด์—ฌ ์ฃผ๊ณ  ์‹ถ์–ด์„œ ํ•ด๋‹น ์กฐ๊ฑด๋ฌธ์„ ์„ค์ •ํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ตณ์ด ์จ ์ฃผ์ง€ ์•Š์•„๋„ ๋ฌธ์ œ ์—†์ด ์ž‘๋™ํ–ˆ๋‹ค.
  4. ๋งŒ์•ฝ ์œ ์ € ๋ชฉ๋ก ์ค‘ ํ•œ ์œ ์ €์˜(people) id๋ฅผ ์†Œ๋ฌธ์žํ™”ํ•œ ๊ฒƒ์—, ์ž…๋ ฅ๋ฐ›์€ ๊ธ€์ž๋ฅผ ์†Œ๋ฌธ์žํ™”ํ•œ ๊ฒƒ์ด ํฌํ•จ๋œ๋‹ค๋ฉด ํ•ด๋‹น ์œ ์ €(people)๋ฅผ return ํ•œ๋‹ค.
  5. ์กฐ๊ฑด์ด ์„ฑ๋ฆฝํ•œ ์œ ์ €๋“ค๋กœ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด์ด ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„๋‹ค. ์ด ๋ฐฐ์—ด์„ .map() ๋ฉ”์„œ๋“œ๋กœ ๋Œ๋ฆฐ๋‹ค.
  6. ๋ณด์—ฌ์ค„ ์œ ์ € UI ํƒœ๊ทธ๋“ค์€ <NavUserSearch />๋กœ ์ปดํฌ๋„ŒํŠธํ™” ํ•ด์ฃผ์—ˆ๋‹ค.
  7. ์ด๋•Œ 5๋ฒˆ์—์„œ ๋งŒ๋“ค์–ด์ง„ ์œ ์ € ๋ฐฐ์—ด๋“ค์„ props๋กœ usersInfo={userArr} ์ „๋‹ฌํ•ด ์ค€๋‹ค.

๐Ÿ“š ๋งˆ์น˜๋ฉด์„œ

  • ๋ฐ”๋‹๋ผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋‹จ์ˆœ ํด๋ก ๋งŒ ํ•  ๋•Œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๋“ฑํ•œ์‹œํ•œ ์ฑ„๋กœ, ๋ฏธ์ ์ธ ๋ฉด์—๋งŒ ์ง‘์ฐฉํ–ˆ์—ˆ๋‹ค. ๋ฌด์กฐ๊ฑด ์ธ์Šคํƒ€๊ทธ๋žจ ์›๋ณธ๊ณผ ๋˜‘๊ฐ™์ด ๋”ฐ๋ผ ํ•˜๋ ค๊ณ , ๋ฏธ์ ์œผ๋กœ ๊น”๋”ํ•˜๊ณ  ์˜ˆ๋ป ๋ณด์ด๋Š” ๊ฒƒ์— ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋’€์—ˆ๋‹ค. ๋‹จ์ˆœ ํด๋ก ์„ ๋๋‚ด๊ณ  ๋‚˜์„œ ๋ฐ˜์„ฑ์„ ๋งŽ์ด ํ–ˆ๋‹ค.

    ๋œ ์˜ˆ์˜๊ฒŒ ๋งŒ๋“ค๋”๋ผ๋„, ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐ ๋ฆฌํŒฉํ† ๋ง ํ€„๋ฆฌํ‹ฐ์— ์šฐ์„  ์ˆœ์œ„๋ฅผ ๋‘๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ–ˆ๋‹ค. ๐Ÿ‘

  • ๋ฆฌ์•กํŠธ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์—์„œ, ๋ฆฌ์•กํŠธ์˜ ๋ฌธ๋ฒ•์— ์ต์ˆ™ํ•ด์ง€๊ณ ์ž ํ•„์ˆ˜ ๊ตฌํ˜„์ด ์•„๋‹Œ ๊ธฐ๋Šฅ๊นŒ์ง€ ๋ชจ๋‘ ๋ฆฌ์•กํŠธ์˜ ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ๊ณ ์น˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค.

  • ๋งˆ์นจ ์ถ”์„ ์—ฐํœด๊ฐ€ ๋ผ์–ด ์žˆ๋˜ ๋•๋ถ„์— ๋งŽ์€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ๋ฒŒ๊ฒŒ ๋˜์–ด ์–ด๋Š ์ •๋„ ๋ฆฌ์•กํŠธ์— ์ต์ˆ™ํ•ด์ง„ ๊ฒƒ ๊ฐ™๋‹ค.

    ํŠนํžˆ state์™€ props๋ฅผ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ• ์ง€ ๊ฐ์„ ์žก์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ํ๋ฅด๊ธฐ์—, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ state์™€ props๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” ๊ฒŒ ์ข‹๋‹ค๋Š” ๊ฒƒ๋„ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ์•˜๋‹ค.

  • ๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ์ด ๋งŽ์„์ˆ˜๋ก ๋ฆฌํŒฉํ† ๋งํ•  ๊ฒƒ์ด ๋งŽ์•„์ง€๊ณ , state์™€ props์˜ ๊ด€๊ณ„๋„ ๋ณต์žกํ•ด์ ธ์„œ ํ—ท๊ฐˆ๋ฆฌ๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ํ•  ๋•Œ๋Š” ์ „์ฒด์ ์ธ ๊ตฌ์กฐ์™€ ์ปดํฌ๋„ŒํŠธ์˜ ๊ด€๊ณ„๋ฅผ ์ƒ๊ฐํ•ด ๊ฐ€๋ฉด์„œ, ํ—ท๊ฐˆ๋ฆผ์ด ๋œํ•˜๊ฒŒ๋” ๋…ธ๋ ฅํ•ด์•ผ๊ฒ ๋‹ค.

  • ๋‚ด๊ฐ€ ์ง  ์ฝ”๋“œ๊ฐ€ ๋ฆฌ์•กํŠธ์— ์–ด์šธ๋ฆฌ๋Š”์ง€ ๊ณ ๋ฏผ์„ ์ •๋ง ๋งŽ์ด ํ•˜๊ฒŒ ๋œ ๊ณ„๊ธฐ๊ฐ€ ๋˜์—ˆ๋‹ค.

    ์›๋ž˜๋„ ์Šค์Šค๋กœํ•œํ…Œ ์—„๊ฒฉํ•œ ํŽธ์ด์ง€๋งŒ, ์ด๋ฒˆ ๋ฆฌ์•กํŠธ ํด๋ก ์„ ํ†ตํ•ด ๊ฒ€์—ด์„ ๋งŽ์ด ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ธฐํšŒ๊ฐ€ ๋˜์—ˆ๋‹ค. ์–ด๋–ค ์ฝ”๋“œ๊ฐ€, ์–ด๋–ค ๋ฐฉ๋ฒ•์ด ๋” ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐ์— ํšจ์œจ์ ์ด๊ณ  ํ•ฉ๋ฆฌ์ ์ธ์ง€์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•˜๊ณ  ๋ฆฌํŒฉํ† ๋ง ํ•˜๋Š” ๋ฐ์— ์‹œ๊ฐ„์„ ์ •๋ง ๋งŽ์ด ์Ÿ์•˜๋‹ค. ๐Ÿ‘

profile
FE Developer

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