๐Ÿ“† 22.10.04 - React ์ดํ•ดํ•˜๊ธฐ (2)

๋ฒ„๋“คยท2022๋…„ 10์›” 6์ผ
0

โœจToday I Learn (TIL)

๋ชฉ๋ก ๋ณด๊ธฐ
3/62

1. Props


Props

๐Ÿ’ก ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ props

props๋กœ ๊ฐ’ ์ „๋‹ฌํ•˜๊ธฐ

// src/App.js

import React from "react";

function App() {
  return <GrandFather />;
}

function GrandFather() {
  return <Mother />;
}

function Mother() {
	const name = 'ํ™๋ถ€์ธ';
  return <Child motherName={name} />; // ๐Ÿ’ก"props๋กœ name์„ ์ „๋‹ฌํ–ˆ๋‹ค."
}

function Child(props) {
  console.log(props) // 'ํฅ๋ถ€์ธ'
  return <div>{props.motherName}</div>; // ๋ Œ๋”๋ง
}

export default App;

์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” ๋จผ์ € Mother์ด๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์ธ Child ์—๊ฒŒ motherName={name} ์„ ์จ์„œ motherName์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ props์จ์„œ name์„ ์ „๋‹ฌ ํ•˜์˜€๋‹ค.

children props

import React from "react";

function User(props) {
  return <div>{props.children}</div>;
}

function App() {
  return <User>์•ˆ๋…•ํ•˜์„ธ์š”</User>;
}
export default App;

๊ธฐ์กด์˜ props ๊ฐ’์„ ์ง€์ •ํ•ด์„œ ๋ณด๋‚ด์ฃผ์ง€ ์•Š์•„๋„, ์ž์‹ ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ๊ฐ’์„ ๋„ฃ๊ณ  ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ {props.children} ํ•˜๋ฉด ๋ Œ๋”๋ง์ด ๋œ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ๋ ˆ์ด์•„์›ƒ ๋งŒ๋“ค ๋•Œ ์šฉ์ดํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

2. State

State

๐Ÿ’ก State๋ž€ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ฐ”๋€” ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์˜๋ฏธํ•œ๋‹ค.
์ƒ์„ฑํ•˜๋ ค๋ฉด useState()์ด๋ž€ ํ›…์„ ์‚ฌ์šฉํ•ด์•ผ๋œ๋‹ค.
// src/App.js

import React, { useState } from "react";

function Child(props) {
  return (
    <div>
      <button
        onClick={() => {
					props.setName("๋ฐ•ํ• ์•„"); // ๋“œ๋””์–ด ๋ฐ›์€ setName์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
        }}
      >
        ํ• ์•„๋ฒ„์ง€ ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐ
      </button>
      <div>{props.grandFatherName}</div>
    </div>
  );
}

function Mother(props) {
  return (
    <Child grandFatherName={props.grandFatherName} setName={props.setName} /> // ๋ฐ›์•„์„œ ๋‹ค์‹œ ์ฃผ๊ณ 
  );
}

function GrandFather() {
  
 /* useState hook์œผ๋กœ 'name' ์ด๋ผ๋Š” state ๊ฐ’๊ณผ, setName์ด๋ผ๋Š” name์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์„ค์ •ํ•ด ์ค€๋‹ค*/
// ๊ทธ ํ›„, ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— state ๊ฐ’๋“ค์„ props๋กœ ๋ณด๋‚ด์ค€๋‹ค. 
  const [name, setName] = useState("๊น€ํ• ์•„");
  return <Mother grandFatherName={name} setName={setName} />; // ์ฃผ๊ณ 
}

function App() {
  return <GrandFather />;
}

export default App;

์œ„์˜ ์˜ˆ์ œ ๊ฐ™์ด state๋Š” ํ˜„์žฌ ์กด์žฌํ•˜๋Š” state๊ฐ’๊ณผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” setState ๊ฐ’์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ state๊ฐ’์„ ๋ง‰ ์ž์œ ์ž์žฌ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ์ข‹์ง€๋งŒ, ์ ˆ๋Œ€ํ•˜๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ์ด ์žˆ๋Š”๋ฐ, ๊ทธ๊ฒƒ์€ ๋ฐ”๋กœ ์›๋ณธ์„ ํ›ผ์†ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ ์ค‘์— ์›์‹œ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ์˜ ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์ฃผ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค.
(์›์‹œ ๋ฐ์ดํ„ฐ๋Š” ๋ถˆ๋ณ€์„ฑ์ด ์žˆ์ง€๋งŒ, ๊ทธ ์™ธ์˜ ๋ฐฐ์—ด, ๊ฐ์ฒด, ํ•จ์ˆ˜๋Š” ๋ถˆ๋ณ€์„ฑ์ด ์—†์Œ)

์ด๋•Œ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ๊นŠ์€ ๋ณต์‚ฌ.. spread operator๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค..!!

import React, { useState } from "react";

function App() {
  const [dogs, setDogs] = useState(["๋งํ‹ฐ์ฆˆ"]);

  function onClickHandler() {
		// spread operator(์ „๊ฐœ ์—ฐ์‚ฐ์ž)๋ฅผ ์ด์šฉํ•ด์„œ dogs๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. 
	  // ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    setDogs([...dogs, "์‹œ๊ณ ๋ฅด์ž๋ธŒ๋ฅด์ข…"]);
  }

  console.log(dogs);
  return (
    <div>
      <button onClick={onClickHandler}>๋ฒ„ํŠผ</button>
    </div>
  );
}

export default App;

3. ๋ฐ˜๋ณต๋˜๋Š” ์ปดํฌ๋„ŒํŠธ

๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ์“ฐ๊ธฐ์—๋Š” ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ํšจ์œจ๋„ ๋ณ„๋กœ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๋ฐฐ์—ด์„ ํ›‘๋Š” map ์„ ํ™œ์šฉ์„ ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜๋ณต์‹œํ‚จ๋‹ค.

๐Ÿ’ก map ์ •๋ง ์ž˜ ์“ฐ์ธ๋‹ค. foreach, filter์™€ ๋”๋ถˆ์–ด.. mdn์„ ๋‹ฌ๋‹ฌ ์™ธ์šฐ์ž..!
(https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

import React from "react";

function User(props) {
  const squareStyle = {
    width: "100px",
    height: "100px",
    border: "1px solid green",
    borderRadius: "10px",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
  };
  return (
    <div style={squareStyle}>
      <div>{props.user.age}์‚ด - </div>
      <div>{props.user.name}</div>
    </div>
  );
}

function App() {
  const style = {
    padding: "100px",
    display: "flex",
    gap: "12px",
  };

  const users = [
    { id: 1, age: 30, name: "์†ก์ค‘๊ธฐ" },
    { id: 2, age: 24, name: "์†ก๊ฐ•" },
    { id: 3, age: 21, name: "๊น€์œ ์ •" },
    { id: 4, age: 29, name: "๊ตฌ๊ตํ™˜" },
  ];

  return (
    <div style={style}>
      {users.map((user) => {
        return <User user={user} key={user.id} />;
      })}
    </div>
  );
}

export default App;

์œ„์˜ ์˜ˆ์ œ์—์„œ map์€ {users.map((user) => { return <User user={user} key={user.id} />; })} ์ด๋ ‡๊ฒŒ ์“ฐ์˜€๋Š”๋ฐ, User๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ์— user์˜ ์ •๋ณด๋ฅผ ์ˆœํšŒํ•˜๊ณ  ๊ฐ๊ฐ์˜ ์ •๋ณด๋ฅผ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

key ๋ž€?

๐Ÿ’ก react์—์„œ๋Š” map์„ ์“ธ ๋•Œ ๊ผญ 'key' ๋ฅผ ์จ์ค˜์•ผํ•œ๋‹ค. (์•ˆ๊ทธ๋Ÿผ ์—๋Ÿฌ๊ฐ€ ๋‚ ์ง€๋„ ๋ชฐ๋ผ์šฉ~)
key๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋Š” react์—์„œ ์ปดํฌ๋„ŒํŠธ ๋ฐฐ์—ด์„ ๋ Œ๋”๋งํ–ˆ์„ ๋•Œ ๊ฐ๊ฐ์˜ ์›์†Œ์—์„œ์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•จ์ด๋‹ค. key๋ฅผ ๋„ฃ์–ด ์ด ๊ฐ’์œผ๋กœ ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ virtual dom์ด ๋น ๋ฅด๊ฒŒ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค. => ket = react ์ตœ์ ํ™”
  • ์‚ฌ์šฉ ์˜ˆ
  <div style={style}>
      {users.map((user) => {
        return <User user={user} key={user.id} />;
      })}
    </div>

4. style component

jsx์—์„œ ์‚ฌ์šฉ๋˜๋Š” css in js ๊ด€๋ จ ๋ฆฌ์•กํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ style component ๋ผ๊ณ  ํ•œ๋‹ค.

styled-components ์„ค์น˜

๋จผ์ € VScode ๋‚ด์—์„œ styled-components ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜

๊ทธ ํ›„ npm i styled-components ํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ํ•ด์ฃผ๊ธฐ

styled-components ์‚ฌ์šฉํ•˜๊ธฐ

import React from "react";
// styled-components์—์„œ styled ๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ import ํ•ฉ๋‹ˆ๋‹ค.
import styled from "styled-components";

// styledํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ styled-components ๋ฐฉ์‹๋Œ€๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 
const StBox = styled.div`
	// ๊ทธ๋ฆฌ๊ณ  ์ด ์•ˆ์— ์Šคํƒ€์ผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ์ฝ”๋“œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” css์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 20px;
`;

const App = () => {
	// ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  styled-components๋ฅผ JSX์—์„œ html ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋“ฏ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  return <StBox>๋ฐ•์Šค</StBox>;
};

export default App;

style-components๋Š” jsx ๋‚ด์—์„œ ๋ณ€์ˆ˜ ๋‚ด์— css ์šฉ์–ด๋ฅผ ์„ž๋Š” ๊ธฐ๋ฒ•์ด๋ฉฐ, ํ˜„์—…์—์„œ๋„ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด ๊ธฐ๋ฒ•์—์„œ์˜ ๊ฐ•์ ์€ style์— ์กฐ๊ฑด๋ถ€ (์‚ผํ•ญ์—ฐ์‚ฐ์ž, if, case ๋“ฑ)์„ ๋‹ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค..!

styled-components ๋ฆฌํŒฉํ† ๋ง

const StContainer = styled.div`
  display: flex;
`;

const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${(props) => props.borderColor};
  margin: 20px;
`;

const App = () => {
	// ๋ฐ•์Šค์˜ ์ƒ‰์„ ๋ฐฐ์—ด์— ๋‹ด์Šต๋‹ˆ๋‹ค.
  const boxList = ["red", "green", "blue"];

  // ์ƒ‰์„ ๋„ฃ์œผ๋ฉด, ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  const getBoxName = (color) => {
    switch (color) {
      case "red":
        return "๋นจ๊ฐ„ ๋ฐ•์Šค";
      case "green":
        return "์ดˆ๋ก ๋ฐ•์Šค";
      case "blue":
        return "ํŒŒ๋ž€ ๋ฐ•์Šค";
      default:
        return "๊ฒ€์ • ๋ฐ•์Šค";
    }
  };

  return (
    <StContainer>
			{/* map์„ ์ด์šฉํ•ด์„œ StBox๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ํ™”๋ฉด์— ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. */}
      {boxList.map((box) => (
        <StBox borderColor={box}>{getBoxName(box)}</StBox>
      ))}
    </StContainer>
  );
};
profile
ํƒœ์–ด๋‚œ ๊น€์— ๋งŽ์€ ๊ฒฝํ—˜์„ ํ•˜๋ ค๊ณ  ์•„๋“ฑ๋ฐ”๋“ฑ ์• ์“ฐ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž

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