๐Ÿ’ช React. Hooks

[meษช]ยท2021๋…„ 9์›” 14์ผ
0

1-3. Today I Learned. React.js

๋ชฉ๋ก ๋ณด๊ธฐ
7/9

๐Ÿ“Œ ๊ฐœ๋ฐœ ๊ณต๋ถ€ 1๊ฐœ์›” ์ฐจ์ธ to-be ๊ฐœ๋ฐœ์ž์˜ ์ž์Šต ๋ธ”๋กœ๊ทธ๐Ÿ™‚๏พ Sep 13 ~ 17, 2021

ํ˜„์žฌ ์ƒํƒœ

React Hooks

App.js๊ฐ€ Hello.js๋ฅผ importํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ

1. components

React๋กœ ๋งŒ๋“  page๋Š” component๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.
์ด์   page ๋‹จ์œ„๋กœ HTML file์„ ๋งŒ๋“œ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ฐ ๋ถ€๋ถ„์„ compoenent๋กœ ๋งŒ๋“ค์–ด ์กฐ๋ฆฝํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
๋น„์Šทํ•œ component๋Š” ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ํŽธํ•˜๋‹ค.
ex. header component, menu component ๋“ฑ

App.js๊ฐ€ ํ•˜๋‚˜์˜ component์ธ๋ฐ, component๋Š” classํ˜•์œผ๋กœ๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ํ•จ์ˆ˜ํ˜•์œผ๋กœ๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

// component folder ๋‚ด file์— code ์ž‘์„ฑ

// ํ•จ์ˆ˜ํ˜• component
const Hello = function() {
  <p>Hello</p>;
};

โ†“ ํ™”์‚ดํ‘œํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝ

const Hello = () => {
  <p>Hello</p>;
};

โ†“ export๊นŒ์ง€ ํ•œ ์ค„๋กœ ์ž‘์„ฑ
export default function Hello(){
  <p>Hello</p>;
}

component๋ช…์€ ์•ž๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ์ ์–ด์•ผ ํ•œ๋‹ค.

component folder๋ฅผ ๋งŒ๋“ค์–ด .js file๋„ ๋งŒ๋“ค๊ณ  ํ•จ์ˆ˜๋„ ๋งŒ๋“ค์–ด์„œ exportํ•˜๋ฉด ํ•„์š”ํ•œ ๊ณณ์—์„œ ํ•ด๋‹น component๋ฅผ importํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

'.js'๋Š” ์ƒ๋žตํ•ด์„œ ์ž‘์„ฑํ•˜๋ฉฐ, importํ•œ ํ›„ HTML tag์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ๊ณณ์— ์ž‘์„ฑํ•œ๋‹ค.

// import๊ฐ€ ํ•„์š”ํ•œ file์— code ์ž‘์„ฑ

import "./App.css";
import Hello from './component/Hello';

function App(){
  return <div className="App">
    <Hello />
  </div>;
}

component๋Š” ์–ด๋””์—์„œ๋“  ๋ช‡ ๋ฒˆ์ด๋“  ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


2. JSX

JSX๋Š” 'JavaScript XML'์˜ ์•ฝ์ž์ด๋‹ค.
ํ•จ์ˆ˜ํ˜• component๋ฅผ ์“ฐ๋ฉด ์ด JSX๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

class๋Š” HTML์˜ ์˜ˆ์•ฝ์–ด์ด๋ฏ€๋กœ JSX์—์„œ๋Š” class ๋Œ€์‹  className์„ ์“ด๋‹ค.

style์€ ๊ฐ์ฒด๋กœ ์ ์–ด์•ผ ์ „๋‹ฌ๋œ๋‹ค.

import ".APP.css"

function App() {
  return <div className="App">
    <h1 style={{
        color: 'red'
    }}>Welcome</h1>
</div>;

export default App;

return ์œ„์—์„œ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ  (const name = "Jane";), return ์•ˆ์—์„œ ์ค‘๊ด„ํ˜ธ์— ๋ณ€์ˆ˜๋ช…์„ ์ž…๋ ฅํ•ด ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ({name})

return ์•ˆ์€ ํ•˜๋‚˜์˜ tag๋กœ ๊ฐ์‹ธ์ ธ์žˆ์–ด์•ผ ํ•œ๋‹ค.


3. styling

๏พ ๏พ 1) ๋ณ„๋„์˜ .scss file์— ๊ธฐ์กด์˜ SCSS ๋ฌธ๋ฒ•์œผ๋กœ ์ž‘์„ฑ
๏พ ๏พ  ๏พ ๏พ (1) ์ถ”ํ›„ ์ž‘์„ฑ

๏พ ๏พ 2) ๋ณ„๋„์˜ .css file์— ๊ธฐ์กด์˜ CSS ๋ฌธ๋ฒ•์œผ๋กœ ์ž‘์„ฑ
๏พ ๏พ  ๏พ ๏พ (1) ๊ฐ .css file์„ ์ƒ์„ฑํ•˜์—ฌ CSS ์ž‘์„ฑ
๏พ ๏พ ๏พ ๏พ ๏พ  ๏พ ๏พ index.css file์— ์ž‘์„ฑํ•œ style์€ ์ „์—ญ์—, component์ด๋ฆ„.css์— ์ž‘์„ฑํ•œ style์€ ๊ฐ component์— ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ ๊ฐ™์ง€๋งŒ clss๋ช…์ด ๊ฐ™์œผ๋ฉด ๊ฐ component.css์— ์ž‘์„ฑํ•œ style๋„ ์ „์—ญ์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ file๋กœ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด (2)๋ฒˆ ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.
๏พ ๏พ  ๏พ ๏พ (2) ๊ฐ .module.css file์„ ์ƒ์„ฑํ•˜์—ฌ CSS ์ž‘์„ฑ
๏พ ๏พ ๏พ ๏พ  ๏พ  ๏พ ๏พ 'styles'๋ฅผ importํ•ด์•ผ ํ•˜๋ฉฐ, CSS component๋ฅผ ์ค‘๊ด„ํ˜ธ ์•ˆ์— ์ ์–ด์•ผ ํ•œ๋‹ค.

import styled from "./App.module.css";
...
  <div className={styles.box}>App</div>

๏พ ๏พ 3) ๋ชจ๋“  style์„ index.css์— ์ž‘์„ฑ
๏พ ๏พ  ๏พ ๏พ component๋‚˜ page๊ฐ€ ๋งŽ์ง€ ์•Š์„ ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•จ

๏พ ๏พ 4) in-line style
๏พ ๏พ  ๏พ ๏พ ๋‹จ, ๊ฐ์ฒด๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ dash๊ฐ€ ์•„๋‹Œ camelCase๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•จ
๏พ ๏พ  ๏พ ๏พ ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด ์›ฌ๋งŒํ•˜๋ฉด in-line์œผ๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š์Œ

<h1
  style = {{
    color: '#f00'
    borderRight: "12px solid #000",
    marginBottom: "50px",
    opacity: 0.5,
}}

4. events

๏พ ๏พ 1) ๋ฏธ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋†“๊ณ  ์ „๋‹ฌ

export default function Hello() {
  function showNmae() {
    console.log("Jane");
}

return (
  <div>
    <button onClick={showName}>Show Name</button>
  </div>
  );
}

๏พ ๏พ  ๏พ ๏พ ์ฐธ๊ณ ๋กœ {showName()}์ด๋ผ๊ณ  ์ ์œผ๋ฉด(์ฆ‰, ํ•จ์ˆ˜๋ช…์— ๊ด„ํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด) return ์œ„์— ์žˆ๋Š” 'ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ํ˜ธ์ถœํ•œ๋‹ค'๋Š” ์˜๋ฏธ์ด๋ฏ€๋กœ 'Jane'์ด ์•„๋‹Œ undefined๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค. ์ง€๊ธˆ์€ showName ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๏พ ๏พ 2) ๋‚ด๋ถ€์— ์ง์ ‘ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑ

export default function Hello() {
  function showNmae(age) {
    console.log(age);
}

return (
  <div>
    <button onClick={() => {
      console.log(30);
    }}
    >Show Name</button>
  </div>
  );
}

๏พ ๏พ  ๏พ ๏พ ์œ„ ๋ฐฉ์‹์œผ๋กœ ํ•˜๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์‰ฝ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, console.log(30); ์ž๋ฆฌ์— showAge(10);์„ ์ž…๋ ฅํ•˜๋ฉด ๋ฐ”๋กœ showAge ๊ฐ’์ด 10์ด ๋œ๋‹ค.


5. state, useState

state๋Š” component๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์†์„ฑ ๊ฐ’์ด๋‹ค.
์ด ์†์„ฑ ๊ฐ’์ด ๋ณ€ํ•˜๋ฉด React๊ฐ€ ์ž๋™์œผ๋กœ UI๋ฅผ updateํ•ด์ค€๋‹ค.

๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋Š” code
changeName ํ•จ์ˆ˜๋Š” name์„ ๋ฐ”๊ฟ”์ฃผ๋Š”๋ฐ, Mike์ผ ๋• Jane์œผ๋กœ Jane์ผ ๋• Mike๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.
return์— {name}์œผ๋กœ ์ด๋ฆ„์„ ํ‘œํ˜„ํ•ด ์ค€๋‹ค.
button์„ ๋งŒ๋“ค์–ด clickํ•˜๋ฉด (onClick) ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์ฃผ๊ฒŒ ํ•œ๋‹ค.

let name = "Mike";

function changeName() {
  name = name === "Mike" ? "Jane" : "Mike";
  consoel.log(name)
}
  
return (
  <div>
    <h2>{name}</h2>
    <button onClick={changeName}>Change</button>
  </div>
);

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์ž…๋ ฅํ•ด๋„ Console tab์—๋งŒ ๊ฐ’์ด ์ž˜ ๋‚˜์˜ฌ ๋ฟ ํ™”๋ฉด์—์„œ๋Š” ์ด๋ฆ„์ด ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค.
๋งŒ์•ฝ Vanilla JavaScript๋กœ codingํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Dom update ์ž‘์—…์„ ํ•ด์ฃผ์–ด์•ผ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
ID๊ฐ€ name์ธ element์˜ text (innerText) ๋ฅผ name์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” code

//Dom update code ์ž…๋ ฅ

let name = "Mike";

function changeName() {
  name = name === "Mike" ? "Jane" : "Mike";
  consoel.log(name);
  document.getElementById("name").innerText = name;
}
  
return (
  <div>
    <h2 id="name">{name}</h2>
    <button onClick={changeName}>Change</button>
  </div>
);

์—ฌ๊ธฐ์—์„œ์˜ name์€ ๋ณ€์ˆ˜์ผ ๋ฟ ์ด React๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” state๊ฐ€ ์•„๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ React๊ฐ€ ๋ณ€๊ฒฝ๋œ ์‚ฌ์‹ค์„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— UI๋ฅผ updateํ•ด์ฃผ์ง€ ์•Š๋Š”๋‹ค.
์ด๋•Œ state๋กœ ๋ฐ”๊พธ์–ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒŒ React Hooks์˜ useState์ด๋‹ค.

React Hooks๋Š” React 16.8๋ถ€ํ„ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, UI component๋งŒ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ํ‘œํ˜„ํ–ˆ๋˜ ์ด์ „๊ณผ ๋‹ฌ๋ฆฌ, ๋ชจ๋“  component๋ฅผ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
์ฆ‰ Hooks์—์„œ๋„ state์™€ lifecycle์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ฐœ๋ฐœ์ž๊ฐ€ ์ž์‹ ๋งŒ์˜ custom Hooks๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.

useState

์ƒํƒœ ๊ฐ’ (state) ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด Hooks์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.

import๋ฅผ ํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

useState๋Š” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€ state์ธ๋ฐ, ์ผ์ข…์˜ ๋ณ€์ˆ˜๋ช…์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
๋‘ ๋ฒˆ์งธ ๊ฐ’์€ state๋ฅผ ๋ณ€๊ฒฝํ•ด ์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

setName ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ผ์„œ name์ด ๋ฐ”๋€Œ๋ฉด React๋Š” ํ•ด๋‹น component๋ฅผ ๋‹ค์‹œ renderingํ•œ๋‹ค.

useState ๊ด„ํ˜ธ ์•ˆ์—” ์ดˆ๊ธฐ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋ฉด ๋œ๋‹ค.

import { useState } from "react";

export default function Hello() {
  const [name, setName] = useState("Mike"); // ๋ฐฐ์—ด ๊ตฌ์กฐ๋ถ„ํ•ด
  
  function changeName() {
    const newName = name === "Mike" ? "Jane" : "Mike";
    setName(newName);
  }
    
  return(
    <div>
      <h2 id="name">{name}</h2>
      <button onClick={changeName}>Change</button>

๊ฐ™์€ component๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ state๊ฐ€ ๊ฐ๊ฐ ๊ด€๋ฆฌ๋˜๋ฉฐ, ๋‹ค๋ฅธ state์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.
ex. <Hello />๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๊ฐ event๊ฐ€ ํ•ด๋‹นํ•˜๋Š” button์— ์˜ํ•ด์„œ๋งŒ ์‹คํ–‰๋จ


6. props

props๋Š” properties์˜ ์•ฝ์ž๋กœ์„œ ์†์„ฑ ๊ฐ’์ด๋‹ค.

์•„๋ž˜์˜ code๋Š” App.js๊ฐ€ Hello.js๋ผ๋Š” component๋ฅผ ์„ธ ๋ฒˆ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด๋‹ค.

import "./App.css";
import Hello from "./component/Hello";

function App() {
  return (
    <div className="App">
      <Hello />
      <Hello />
      <Hello />
    </div>
  );
}

export default App;

์—ฌ๊ธฐ์—์„œ ๋งŒ์•ฝ <Hello />์— ํ•จ์ˆ˜๋ฅผ ์ž…๋ ฅํ•˜๋ฉด Hello.js ํ•จ์ˆ˜๋กœ ์ž…๋ ฅํ•œ ๊ฐ’์ด ์ „๋‹ฌ๋œ๋‹ค.

import "./App.css";
import Hello from "./component/Hello";

function App() {
  return (
    <div className="App">
      <Hello age={10}/>
      <Hello age={20}/>
      <Hello age={30}/>
    </div>
  );
}

export default App;

Hello.js์—์„œ export default function Hello() { ๋ถ€๋ถ„์„ export default function Hello(props) {๋กœ ์ˆ˜์ •ํ•ด์•ผ App.js์— ์žˆ๋Š” {age} ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

import { useState } from "react";

export default function Hello(props) {
  const [name, setName] = useState("Mike");
    
  return(
    <div>
      <h2 id="name">{name}({props.age})</h2>
      <button onClick={() => {
          setName(name === "Mike" ? "Jane" : "Mike");
        }}
        >Change
      </button>
    </div>

์ด ์ƒํƒœ์—์„œ๋Š” Hello.js๊ฐ€ {age}๋ฅผ App.js๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— props์ธ Hello.js์—์„œ๋Š” {age}๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค. (Read Only) Hello.js์—์„œ age๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ƒˆ๋กญ๊ฒŒ state๋ฅผ ์„ค์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ex. const [age, setAge] = useState(props.age);


7. mockup data, map

map()์€ ๋ฐฐ์—ด์„ ๋ฐ›์•„์„œ ๋˜ ๋‹ค๋ฅธ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
๋ฐฐ์—ด ์š”์†Œ๋Š” JSX๋กœ ์ž‘์„ฑํ•˜๊ณ  ํ™”์‚ดํ‘œํ•จ์ˆ˜๋กœ ๋ฐ”๋กœ return๋ฌธ์„ ์ž‘์„ฑํ•œ๋‹ค.

import mockdata from "..db/data.json";

export default function DayList() {
  return (
    <ul className="list_day">
      {mockdata.days.map(day => (
        <li>Day {day.day}</li>
     ))}
   </ul>
  );
}

์ด๋•Œ ๊ฐœ๋ฐœ์ž๋„๊ตฌ์—์„œ Warning: Each child in a list should have a unique "key" prop.์ด๋ผ๋Š” ๊ฒฝ๊ณ ๋ฌธ์ด ๋œจ๋Š”๋ฐ, ๋ฐ˜๋ณต๋˜๋Š” ์š”์†Œ์— key๋ผ๋Š” ๊ณ ์œ ํ•œ ์š”์†Œ๋ฅผ ์ž…๋ ฅํ•˜๋ผ๋Š” ๋œป์ด๋‹ค.
์ด๋ฅผ ์œ„ํ•ด code๋ฅผ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

import mockdata from "..db/data.json";

export default function DayList() {
  return (
    <ul className="list_day">
      {mockdata.days.map(day => (
        <li key={day.id}>Day {day.day}</li>
     ))}
   </ul>
  );
}

8. routing, useParams

react-router-dom

react-router-dom์„ ์„ค์น˜ํ•œ ํ›„ App.js์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.

import { BrowserRouter, Route, Switch } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <Switch>
          <Route exact path ="/" />
          <Route path="/day" />
        </Switch>
      </div>
    </BrowserRouter>
  );
}

<Switch /> ๋ฐ–์— ์žˆ๋Š” ๊ฒƒ์€ ๊ณ ์ •๋œ component์ด๊ณ , ์•ˆ์— ์žˆ๋Š” ๊ฒƒ์€ ๋ณ€๋™๋œ๋‹ค.
Route exact path ="" />๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ฃผ์†Œ๊ฐ€ ์ •ํ™•ํ•  ๋•Œ๋งŒ page๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
Route path ="/day" />๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ฃผ์†Œ์— '/day'๊ฐ€ ์žˆ์œผ๋ฉด ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š๋”๋ผ๋„ page๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

useParams

useParams๋ฅผ ์ด์šฉํ•ด ์ฃผ์†Œ์ฐฝ์— ์žˆ๋Š” ๋ฌธ์ž์—ด์ด ์ž…๋ ฅ๋œ๋‹ค.
<Route path="/day/:id">๋ผ๊ณ  ์ž…๋ ฅํ•˜๊ณ  component์—์„œ useParms๋ฅผ importํ•˜๋ฉด URL์ด ๊ฐ™์ด ๋ฐ”๋€๋‹ค. (${day} ๋ถ€๋ถ„)

import { useParams } from "react-router-dom";

export default function Day() {
  const { day } = useParams();
  
  useEffect(() => {
    fetch('http://localhost:3001/words?day=${day}`)
      .then(res => {
  		return res.json);
      }) ...

HTML์—์„œ๋Š” <a /> tag๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, React Router๋Š” <Link /> tag๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
import๋ฅผ ํ•œ ํ›„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. import { Link } from "react-router-dom";
<Link to="/day">Day {day.day}</Link> ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค.
์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•ด๋„ ๊ฐœ๋ฐœ์ž‘๋„๊ตฌ Elements tab์—๋Š” <a />tag๋กœ ํ‘œ๊ธฐ๋œ๋‹ค.


8. json server, RESTful API

json server

terminal์—์„œ npm install -g json-server ์ดํ›„ json-server --watch ./src/db/data.json --port 3001 ํ•˜๊ณ  clickํ•˜๋ฉด ๋‚ด๊ฐ€ editor์—์„œ ๋งŒ๋“  mockup data๊ฐ€ ๋œฌ๋‹ค.

REST API

REST API๋Š” URI ์ฃผ์†Œ์™€ method๋กœ CRUD๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  • CRUD์™€ method
    • Create : POST
    • Read : GET
    • Update : PUT
    • Delete : DELETE

URI๋งŒ ๋ณด๊ณ ๋„ ์–ด๋–ค ์š”์ฒญ์ธ์ง€ ์ง์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
ex. localhost:3002/words?day=1

์ด์ „๊นŒ์ง€ ํ•œ ์ž‘์—…์€ ์ƒˆ๋กœ๊ณ ์นจํ•˜๋ฉด ์›๋ž˜๋Œ€๋กœ ๋Œ์•„์™”์ง€๋งŒ, ์ง€๊ธˆ๋ถ€ํ„ฐ ํ•˜๋Š” ์ž‘์—…์€ data์— ๋ฐ˜์˜๋  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด๋„ ์›๋ž˜๋Œ€๋กœ ๋Œ์•„๊ฐ€์ง€ ์•Š๋Š”๋‹ค.


9. API call

useEffect

useState์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ importํ•ด์•ผ ํ•œ๋‹ค. import { useEffect, useState } from "react";

์ƒํƒœ ๊ฐ’์ด ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
useEffect์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•จ์ˆ˜๋ฅผ ๋„ฃ๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” timing์€ rendering ๊ฒฐ๊ณผ๊ฐ€ ์‹ค์ œ DOM์— ๋ฐ˜์˜๋œ ์งํ›„์ด๋ฉฐ component๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ง์ „์—๋„ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ˜ธ์ถœ๋œ๋‹ค.

useEffect์˜ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์˜์กด์„ฑ๋ฐฐ์—ด์„ ๋„ฃ๋Š”๋ฐ, ์˜์กด์„ฑ๋ฐฐ์—ด์„ ๋„ฃ์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ event๊ฐ€ ์ง„ํ–‰๋  ๋•Œ๋„ ์‹ค์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์˜์กด์„ฑ๋ฐฐ์—ด์— ์˜๋„ํ•˜๋Š” ํ•จ์ˆ˜๋ช…์„ ๋„ฃ์–ด ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ์ง„ํ–‰ ๋• ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ํ•ด์ฃผ์–ด์•ผ ๋™์ž‘์— ๋ฌด๋ฆฌ๊ฐ€ ์—†๋‹ค.

useEFfect๋Š” rendering ํ›„ API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๋•Œ์—๋Š” ์˜์กด์„ฑ๋ฐฐ์—ด์„ ๋นˆ ๋ฐฐ์—ด๋กœ ๋น„์›Œ๋‘”๋‹ค.

์ƒํƒœ ๊ฐ’๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ rendering ์งํ›„ ๋”ฑ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์„ ๋นˆ ๋ฐฐ์—ด๋กœ ์ž‘์„ฑํ•œ๋‹ค.

fetch


React ๊ณต์‹ ๋ฌธ์„œ

๐Ÿ™‡ the source of this content

์ฝ”๋”ฉ์•™๋งˆ





from Nomad Coders

react hooks๋Š” functional component์— state๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
(์›๋ž˜๋Š” class component๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์—ˆ์Œ)
react hooks์„ ์‚ฌ์šฉํ•˜๋ฉด class component, CMD(componentDidMount), render ์ด๋Ÿฐ ๊ฒƒ๋“ค์„ ์•ˆ ํ•ด๋„ ๋จ
๋ชจ๋“  ๊ฒƒ์ด ํ•˜๋‚˜์˜ function์ด ๋จ
๊ฒฐ๊ตญ funtional programming style์ด ๋˜๋Š” ๊ฒƒ

hooks์˜ ์‹œ์ดˆ์ธ recompose
hooks์˜ ๊ณต์‹ ๋ฌธ์„œ hooks

useState

counting with class component

  • class component๊ฐ€ ํ•„์š”
  • state ํ•„์š”
  • state ์ •์˜ ํ•„์š”
  • render ๋‹ค์Œ์œผ๋กœ ํŒจ์Šค ํ•„์š”
  • etc
import React, { Component } from "react";
class App extends Component {
	state = {
		count : 0
};
modify = (n) => {
	this.setState({
    count:n
    });
};
render() {
	const { count } = this.state;
	return (
            <>
            	<div>{count}</div>
            	<button onClick{() => this.modify(count + 1)}>Increment</button>
            </>;
       );
    }
}
export default App;

counting with hooks

  • ๋” ๊ฐ„๊ฒฐํ•จ
  • state๋ฅผ ๋‹ค ๋”ฐ๋กœ ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ๋จ
import React, { Component, useState } from "react";
const App = () => {
	const [count, setCount] = useState(0);
    return (
    <>
    	{count}
        <button onClick={() => setCount(count + 1)}>Increment</button>
    </>
    );
};
export default App;
  • useState๋Š” value์™€ value๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์คŒ
  • ๋ณ€์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ์ •์˜ํ•œ ์ด์œ ๋Š” useState๊ฐ€ ์ฃผ๋Š” ๊ฒƒ์ด array์ด๊ธฐ ๋•Œ๋ฌธ const [count(์ฒซ ๋ฒˆ์งธ ์š”์†Œ), setCount(๋‘ ๋ฒˆ์งธ ์š”์†Œ)]
  • useState๋Š” array๋ฅผ returnํ•  ๊ฑฐ๊ณ , ๊ทธ array์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋Š” value, ์ด value๋Š” 0์—์„œ ์‹œ์ž‘ํ•จ
  • array์˜ ๋‘ ๋ฒˆ์งธ ์š”์†Œ๋Š” setCount
  • ์ฐธ๊ณ ๋กœ count, setCount ์ž๋ฆฌ์—๋Š” ์•„๋ฌด ๋ง์ด๋‚˜ ์ ์–ด๋„ ๋˜์ง€๋งŒ ์ง€๊ธˆ์ฒ˜๋Ÿผ ์ ๋Š” ๊ฒŒ convention์ž„

class component์—์„œ๋Š” react state management๋ฅผ ์ผ์ผ์ด ์ ์–ด์•ผ ํ–ˆ๋Š”๋ฐ
useState๋Š” react state management ๋ฐ‘์œผ๋กœ ๋“ค์–ด๊ฐ€ hook์„ ๋•ก๊ธฐ๋Š” ๊ฑฐ์•ผ(?)

์ถ”๊ฐ€๋กœ input์„ ๋งŒ๋“ค์–ด ๋ณด๋ฉด

import React, { Component, useState } from "react";
const App = () => {
	const [count, setCount] = useState(0);
    const [email, setEmail] = useState("");
    const undateEmail = e => {
    	const {
        	target: { value }
        } = e;
        setEmail(value);
    };
    return (
    <>
    	{count}
        <button onClick={() => setCount(count + 1)}>Increment</button>
        <input placeholder="Email" value={email} onChange={updateEmail} />
    </>
    );
};
export default App;

useEffect

componentDidMount๋‚˜ componentDidUpdate์™€ ๋น„์Šทํ•จ (์ด๊ฒƒ๋“ค์€ ์ฃผ๋กœ API ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•  ๋•Œ ์‚ฌ์šฉํ•จ)


https://www.notion.so/wecode/React-Hooks-b07fdc9d5d82470492a0b4fa8e800c41

intro
ํ•จ์ˆ˜ ์ปดํผ๋„ŒํŠธ๋ž‘ ํ›…์Šค๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๊ฑฐ์ž„

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ํŠน์ง•๊ณผ hooks์˜ ํ•„์š”์„ฑ ์ดํ•ด
hook๋Š” 2018๋…„์— ์ฒซ ๊ณต๊ฐœ
hook์€ ๊ทธ๋ƒฅ ํ•จ์ˆ˜์•ผ

useState hook์„ ์‚ฌ์šฉํ•ด React์˜ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌ
useEffect hook์„ ์‚ฌ์šฉํ•ด React ์ปดํฌ๋„ŒํŠธ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌ

๊ธฐ์กด ๊ฐœ๋…์˜ ๋‹ค๋ฅธ ํ‘œํ˜„์ผ ๋ฟ

(์ฐธ๊ณ ) Dan Abramov๋Š” Create React ๋งŒ๋“  ์‚ฌ๋žŒ์ด๊ณ , Facebook ๊ฐœ๋ฐœ์ž์ธ๋ฐ useEffect์— ๋Œ€ํ•ด ์•„์ฃผ ์ƒ์„ธํžˆ ์„ค๋ช…ํ•ด ๋†“์•˜์Œ


body hooks๋ฅผ ์™œ ์จ์•ผ ํ•˜๋Š”์ง€? ๊ณต์‹ ๋ฌธ์„œ ํ•„๋… ํ˜„์—…์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•จ

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” state๋ž‘ lifecycle์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
hooks์˜ ๋“ฑ์žฅ์œผ๋กœ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋„ state์™€ lifecycle์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
hooks๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋กœ ์จ์•ผ ํ•จ
ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ž‘ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ํ˜ธํ™˜๋จ

์ปดํฌ๋„ŒํŠธ๋Š” ๋ผ์šฐํŠธ ๊ธฐ๋Šฅ ์—†์ง€๋งŒ withRoute๋กœ ์“ฐ์ž–์•„, ์ด๊ฒƒ์ฒ˜๋Ÿผ

ํ•œ ์ปดํฌ๋„ŒํŠธ์—” lifecycle ํ•˜๋‚˜๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ ์กฐ๊ฑด๋ฌธ ๊ฐ™์€ ๊ฒƒ๋“ค์„ ํ•˜๋‚˜์˜ method์— ๋‹ค ๋„ฃ์–ด์•ผ ํ–ˆ์–ด
ํ•˜์ง€๋งŒ useEffect๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด...

ํ•˜์••

๊ธฐ์Šน์ „ useState...

์ด์ œ useEffect
useEffect๋„ ํ•จ์ˆ˜
๋’ค์— ์†Œ๊ด„ํ˜ธ ์žˆ์Œ

useEffect(๋™์ž‘ function, ํƒ€์ด๋ฐ Array)
๋ฅผ ์•„๋ž˜์— ๋น„์œ ํ•˜๋ฉด

window.addEventListener("click", () => {
console.log("click!")
})

window.addEventListener(์ด๋ฒคํŠธ ์ข…๋ฅ˜(ํƒ€์ด๋ฐ), ๋™์ž‘ function)

useEffect(() => {
console.log("trigger!!")
})

profile
๋Š๋ ค๋„ ํ•  ๊ฑฐ์•ผ.......

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