TIL 220808

HaByungNo·2022년 8월 8일
0

Today I Learned

목록 보기
10/16
post-thumbnail

Done 😁



Learned 👌

useEffect()

리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook
useState와 마찬가지로 React에서 제공하는 훅 (기능) 이므로,
import React, { useEffect } from "react"; 로 import 해서 사용

// src/App.js

import React, { useEffect } from "react";

const App = () => {
  useEffect(() => {
    console.log("hello useEffect"); // 이 부분이 실행된다.
  });
  return <div>Home</div>;
}

export default App;

브라우저에서 우리가 App 컴포넌트를 눈으로 보는 순간, 즉 App 컴포넌트가 화면에 렌더링될 때 useEffect 안에 있는 console.log가 컴포넌트가 렌더링 될 때 실행된다.

하지만 만약 이런 코드가 있다면 어떻게 될까?

import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  useEffect(() => {
    console.log("hello useEffect");
  });

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
        }}
      />
    </div>
  );
}

export default App;

input이 있고 value 라는 state를 생성하여 input과 연결시켰다. 이렇게 구현하고 브라우저에 input에 어떤 값을 입력하면 리랜더링이 계속 일어나서 useEffect가 계속 실행되는 것을 볼 수 있다.

즉,

  1. input에 값을 입력한다.
  2. value, 즉 state가 변경된다.
  3. state가 변경되었기 때문에, App 컴포넌트가 리렌더링 된다.
  4. 리렌더링이 되었기 때문에 useEffect가 다시 실행된다.
  5. 1번 → 5번 과정이 계속 순환환다.

이 과정이 계속 반복되는 것이다.

따라서 이 현상을 해결하기 위해 사용하는것이 의존성 배열(dependency array)이다.

의존성 배열(dependency array)
이 배열에 값을 넣으면 그 값이 바뀔 때만 useEffect를 실행하게 된다.

// useEffect의 두번째 인자가 의존성 배열이 들어가는 곳 입니다.
useEffect(()=>{
	// 실행하고 싶은 함수
}, [의존성배열])
  • 의존성 배열이 빈 배열인 경우
    의존성 배열은 “이 배열에 값을 넣으면 그 값이 바뀔 때만 useEffect를 실행할게” 라는 의미를 가진다. 따라서 아무것도 넣지 않았으니 useEffect는 처음에 딱 한번만 실행되고 그 이후로는 어떤일이 일어나도 실행이 되지 않는다.
// src/App.js

import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log("hello useEffect");
  }, []); // 비어있는 의존성 배열

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
        }}
      />
    </div>
  );
}

export default App;
  • 의존성 배열에 값이 있는 경우
    빈 배열을 넣었을 때, 최초 렌더링 이후에는 useEffect가 실행되지 않는다는 것을 알았다. 그렇다면 이제 의존성 배열에 value 를 넣어보자. 배운게 맞다면, value는 state 이고 우리가 input을 입력할 때마다 그 값이 변하게 되니 useEffect도 계속 실행이 되게된다
// src/App.js

import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log("hello useEffect");
  }, [value]); // value를 넣음

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
        }}
      />
    </div>
  );
}

export default App;


Axios

// url에는 서버의 url이 들어가고, config에는 기타 여러가지 설정을 추가할 수 있습니다.
// config는 axios 공식문서에서 확인하세요.

axios.get(url[, config]) // GET
axios.post(url[, data[, config]])   // POST
axios.delete(url[, config])  // DELETE
axios.patch(url[, data[, config]])  // PATCH

Axios 공식문서

// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios";

const App = () => {
  const [todo, setTodo] = useState({
    title: "",
  });
  const [todos, setTodos] = useState(null);

  // patch에서 사용할 id, 수정값의 state를 추가
  const [targetId, setTargetId] = useState(null);
  const [editTodo, setEditTodo] = useState({
    title: "",
  });

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data);
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:3001/todos", todo);
  };

  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:3001/todos/${todoId}`);
  };

  // 수정버튼 이벤트 핸들러 추가 👇
  const onClickEditButtonHandler = (todoId, edit) => {
    axios.patch(`http://localhost:3001/todos/${todoId}`, edit);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        {/* 👇 수정기능에 필요한 id, 수정값 input2개와 수정하기 버튼을 추가 */}
        <div>
          <input
            type="text"
            placeholder="수정하고싶은 Todo ID"
            onChange={(ev) => {
              setTargetId(ev.target.value);
            }}
          />
          <input
            type="text"
            placeholder="수정값 입력"
            onChange={(ev) => {
              setEditTodo({
                ...editTodo,
                title: ev.target.value,
              });
            }}
          />
          <button
						// type='button' 을 추가해야 form의 영향에서 벗어남
            type="button"
            onClick={() => onClickEditButtonHandler(targetId, editTodo)}
          >
            수정하기
          </button>
        </div>
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
						{/* todo의 아이디를 화면에 표시 */}
            {todo.id} :{todo.title}
            <button
              type="button"
              onClick={() => onClickDeleteButtonHandler(todo.id)}
            >
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;


profile
프라고

0개의 댓글