프론트엔드/React

리액트 Hooks

alswlfl 2022. 11. 15. 21:41

- 리액트 16.8 이전 버전에서는 함수형 컴포넌트에서 상태를 관리할 수 없었지만, 리액트 16.8에서 Hooks라는 기능이 도입되면서 함수형 컴포넌트에서도 상태 관리할 수 있게 됨

이벤트 설정

import React from "react";

function Counter() {
  const onIncrease = () => {
    console.log("+1");
  };

  const onDecrease = () => {
    console.log("-1");
  };

  return (
    <div>
      <h1>0</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

- 이벤트 설정해줄 때, on이벤트이름={실행하고싶은함수} 형태로 설정

import React from "react";
import Counter from "./Counter";

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

export default App;

useState

: 컴포넌트에서 동적인 값을 상태(state)라고 부름, useState함수 이용해 컴포넌트에서 상태 관리 가능

import React, { useState } from "react";

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber(number + 1);
  };

  const onDecrease = () => {
    setNumber(number - 1);
  };

  return (
    <div>
      <h1>0</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

함수형 업데이트

import React, { useState } from "react";

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber((prevNumber) => prevNumber + 1);
  };

  const onDecrease = () => {
    setNumber((prevNumber) => prevNumber - 1);
  };

  return (
    <div>
      <h1>0</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

⭐️ 화살표 함수

: 함수를 선언하는 방식 중 또 다른 방법으로, function 키워드 대신 => 문자를 사용해서 함수 구현

const add =(a,b) =>{
	return a+b;
};

console.log(add(1,2));

input 상태 관리

e.target이벤트가 발생한 DOM을 가리킴

이 DOM의 value 값, 즉 e.target.value를 조회하면 현재 input에 입력한 값이 무엇인지 알 수 있음

import React, { useState } from "react";

function InputSample() {
  const [text, setText] = useState("");

  const onChange = (e) => {
    setText(e.target.value);
  };
  const onReset = () => {
    setText("");
  };
  return (
    <div>
      <input onChange={onChange} value={text} />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: {text}</b>
      </div>
    </div>
  );
}

export default InputSample;

- input의 상태 관리 시, input 태그의 value 값도 설정해주는 것이 중요함 -> 상태가 바뀌었을 때 input의 내용도 업데이트 됨

여러개의 input 상태 관리

▸ placeholder: input의 속성 중 하나로, input이 비어져있을 때 input에 대한 설명을 보여줌

 

input의 개수가 여러개가 되었을 때, 단순히 useState를 여러번 사용하고, onChange도 여러 개 만들어서 구현하는 방식은 좋은 방법이 아님

input에 name을 설정하고 이벤트가 발생했을 때 이 값을 참조하는 방식이 좋음, useState에서는 문자열이 아닌 객체 형태의 상태를 관리해주어야 함
import React, { useState } from "react";

function InputSample() {
  const [inputs, setInputs] = useState({
    name: "",
    nickname: "",
  });
  const { name, nickname } = inputs; //비구조화 할당을 통해 값 추출

  const onChange = (e) => {
    const { value, name } = e.target; //우선 e.target에서 name과 value를 추출
    setInputs({
      ...inputs, //기존의 input객체 복사한 뒤
      [name]: value, //name키를 가진 값을 value로 설정
    });
  };
  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
  };
  return (
    <div>
      <input name="name" placeholder="이름" onChange={onChange} value={name} />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값:</b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

- 새로운 객체를 만들어서 새로운 객체에 변화를 주고, 이를 상태로 사용해주어야 함(리액트 상태에서 객체 수정할 경우, inputs[name]=value; 이렇게 직접 수정하면 안됨)

setInputs({
	...inputs,
    [name]: value
});

- 불변성을 지켜주어야 리액트 컴포넌트에서 상태가 업데이트가 됐음을 감지할 수 있고, 이에 따라 필요한 리렌더링 진행

- 리액트에서는 불변성을 지켜주어야만 컴포넌트 업데이트 성능 최적화를 제대로 할 수 있음

⭐️ spread문법

...문법(spread 문법):  기존의 것을 건들이지 않고, 새로운 객체를 만듦(객체의 내용을 모두 펼쳐서 기존 객체를 복사)

const animals=['개','고양이','참새'];
const anotherAnimals=[...animals, '비둘기'];
console.log(animals);
console.log(anotherAnimals);