프로그래밍/React

[React] 초보자를 위한 리액트 강좌 2

라다디 2022. 1. 16. 11:30

 

이벤트 처리

1. 미리 함수로 만들어서 전달

onClick={함수명}

문자열이 아니기 때문에 중괄호 사용

// Hello.js
export default function Hello() {
  function showName() {
    console.log("Mike");
  }

  return (
    <div>
      <h1>Hello</h1>
      <button onClick={showName}>show name</button>
      <button>show age</button>
    </div>
  );
}

만일 showName()과 같이 함수 뒤에 ()을 붙여주면 함수가 반환하는 값이 들어감

현재는 반환값이 없으니 undefined

 

2. onClick 내부에 직접 함수 작성

<button
  onClick={() => {
    console.log(30);
  }}
>
  show age
</button>

이 방법의 장점은 매개변수를 전달하기가 편하다는 점

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

  return (
    <div>
      <h1>Hello</h1>
      <button
        onClick={() => {
          showAge(10);
        }}
      >
        show age
      </button>
    </div>
  );
}

 

3. 이벤트 객체 받기

// (1)
export default function Hello() {
  function showText(e) { // 이벤트 객체
    console.log(e.target.value); // target은 input태그, value는 input의 값
  }

  return (
    <div>
      <h1>Hello</h1>
      <input type="text" onChange={showText} />
    </div>
  );
}
// (2) showText사용 x
<input type="text" onChange={(e) => {
  console.log(e.target.value)
}} />

// (3)
export default function Hello() {
  function showText(txt) {
    console.log(txt); 
  }

  return (
    <div>
      <h1>Hello</h1>
      <input type="text" onChange={(e) => {
        const txt = e.target.value;
        showText(txt)
      }} />
    </div>
  );
}

 

아래와 같이 console에 로그가 찍히는 것을 볼 수 있음

 

state, useState

state는 컴포넌트가 가지고 있는 속성값

속성값이 변하면 리액트는 자동으로 UI를 업데이트 시켜줌

 

@ change 버튼을 누르면 이름이 바뀌는 코드

아래 코드에서 name은 state가 아니라 변수일 뿐 컴포넌트가 관리하고 있는 상태값이 아님

그래서 바뀌어도 리액트가 인지하지 못해 UI를 업데이트하지 못하기 때문에 

태그에 아이디를 지정해주고 자바스크립트 코드를 사용해서 dom을 업데이트 해줌

export default function Hello() {
  let name = "Mike";

  function changeName() {
    name = name === "Mike" ? "Jane" : "Mike";
    console.log(name);
    document.getElementById("name").innerText = name;
  }

  return (
    <div>
      <h1>state</h1>
      <h2 id="name">{name}</h2>
      <button onClick={changeName}>Change</button>
    </div>
  );
}

 

그러면 어떻게 해야 state를 만들 수 있을까?

-> useState사용!

 

초기 리액트는 state와 lifecycle을 관리하려면 클래스형 컴포넌트를 만들고

UI 표현은 함수형 컴포넌트로 표현했음

 

버전 업데이트가 되면서 리액트 훅(ex. useState)을 이용해서 함수형 컴포넌트에서도

state와 lifecycle관리가 가능해졌음

 

useState는 사용하려면 import

import {useState} from "react";

 

const [name, setName] = useState('Mike'); // 배열 구조 분해

useState는 배열을 반환

배열의 첫 번째 값은 state (변수명이라 생각)

두 번째는 state를 변경해주는 함수

괄호 안에는 초기값

setName함수가 호출되어 name이 바뀌면 리액트는 컴포넌트(Hello)를 다시 렌더링

// Hello.js
import { useState } from "react";

export default function Hello() {
  const [name, setName] = useState("Mike");

  return (
    <div>
      <h2 id="name">{name}</h2>
      <button
        onClick={() => {
          setName(name === "Mike" ? "Jane" : "Mike");
        }}
      >
        Change
      </button>
    </div>
  );
}

 

동일한 컴포넌트라도 state는 각각 관리됨

 

 

props

properties의 약자로 속성값을 의미

 

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

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

export default App;
import { useState } from "react";

export default function Hello(props) {
  console.log(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>
  );
}
React는 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달합니다. 이 객체를 “props”라고 합니다.

https://ko.reactjs.org/docs/components-and-props.html

 

props의 값은 컴포넌트 내부에서 수정 불가능

넘겨받은 그대로 사용해야 함

 

값을 변경하고 싶다면 컴포넌트 내부에서 state를 다시 만들어야 함

@ 클릭할 때마다 나이가 증가

import { useState } from "react";

export default function Hello(props) {
  console.log(props);
  const [name, setName] = useState("Mike");
  const [age, setAge] = useState(props.age);

  return (
    <div>
      <h2 id="name">
        {name}({age})
      </h2>
      <button
        onClick={() => {
          setName(name === "Mike" ? "Jane" : "Mike");
          setAge(age + 1);
        }}
      >
        Change
      </button>
    </div>
  );
}

넘겨받은 값을 직접 변경하는 것은 아님

props.age = 10; 

이런식으로 코드를 짜면 에러가 발생

 

속성을 전달받을 때 현재 age만 사용하고 있으므로 

export default function Hello({ age }) 

이런식으로 사용하는 것도 가능 -> 이해가 안가면 구조 분해 할당 공부

import { useState } from "react";

export default function Hello({ age }) {
  const [name, setName] = useState("Mike");
  const msg = age > 19 ? "성인 입니다." : "미성년자 입니다.";

  return (
    <div>
      <h2 id="name">
        {name}({age}) : {msg}
      </h2>
      <button
        onClick={() => {
          setName(name === "Mike" ? "Jane" : "Mike");
        }}
      >
        Change
      </button>
    </div>
  );
}

 

한 컴포넌트의 state를 다른 컴포넌트의 props로 전달하는 것도 가능

// UserName.js
export default function UserName({ name }) {
  return <p>Hello, {name}</p>;
}
import { useState } from "react";
import UserName from "./UserName";

export default function Hello({ age }) {
  const [name, setName] = useState("Mike");
  const msg = age > 19 ? "성인 입니다." : "미성년자 입니다.";

  return (
    <div>
      <h2 id="name">
        {name}({age}) : {msg}
      </h2>
      <UserName name={name} /> // (A)
      <button
        onClick={() => {
          setName(name === "Mike" ? "Jane" : "Mike");
        }}
      >
        Change
      </button>
    </div>
  );
}

(A)의 name은 Hello 컴포넌트에서는 state지만 

UserName 컴포넌트 입장에서는 props

 


📌 아래 강의의 내용을 정리한 글입니다.