[React Hooks] useState, useEffect

박은지·2022년 2월 19일
0

Todo Application

목록 보기
1/7

💡 본 프로젝트는 Youtube 코드스쿼드님의 Todo Application 을 수강하며 기록한 클론 프로젝트입니다.

1. create-react-app

cmd 명령 프롬프트 창에 create-react-app 명령을 통해 리액트 프로젝트를 생성한다.

  • cd : 위치 이동
  • mkdir : 디렉토리 생성하기
  • npx create-react-app 프로젝트명 : 리액트 앱 생성하기
  • npm start : 브라우저에서 리액트 앱 실행하기

2. App.js 수정하기

프로젝트 디렉토리 안에 있는 src 폴더에서 App.js라는 폴더의 소스 코드를 수정하고 결과를 확인해보자.

App.js

// App.js ---------------------------------------------------------//

import './App.css';
// components
import List from './components/List.jsx';

function App() {
  return(
    <>
      <h1>Todo Application</h1>

      <form action="">
        <input type="text" name="" />
        <button>ADD</button>
      </form>
    </>
  );
}

export default App;

3. List Component

src 폴더안에 컴포넌트들을 담을 components폴더를 생성한 후, List.jsx 파일을 생성한다.
이 파일에 List component에 대한 소스코드를 작성할 것이다.

// List.jsx -------------------------------------------------------//

import React from 'react';

function List() {
  return(
    <ul>
      <li>Java 공부하기</li>
      <li>React 공부하기</li>
      <li>운동하기</li>
    </ul>
  );
}

export default List;

4. React Hooks

React Hook 공식문서

useState Hook

useState Hook 공식문서
React에서는 상태관리를 할 때 useState라는 Hook을 사용한다.

useState Hook 불러오기

import React, { useState } from 'react';

useState 선언

const [ state변수명 , setState함수 ] = useState( 초기값 );

[1] 할 일 목록 보여주기

App.js
['Java 공부하기', 'React 공부하기', '운동하기'] 배열을 todos의 초깃값으로 지정한다.
이 todos에 담긴 상태를 List 컴포넌트에 전달하여 배열안에 담긴 todo 목록들을 하나씩 보여줄 것이다.

// App.js ---------------------------------------------------------//

import React, { Component, useState } from 'react';
import './App.css';
// components
import List from './components/List.jsx';

function App() {

  // ----- useState ----- //
  const [todos, setTodos] = useState(['Java 공부하기', 'React 공부하기', '운동하기']);

  return(
    <>
      <h1>Todo Application</h1>

      <form action="">
        <input type="text" name="" />
        <button>ADD</button>
      </form>

      <List todos={todos} />
    </>
  );
}

export default App;

List.jsx
List 컴포넌트에서는 App.js로부터 전달받는 todos 배열안에서 todo 목록을 하나씩 꺼내어 <li>{todo}</li> 형태로 렌더링한다.

// List.jsx -------------------------------------------------------//

import React from 'react';

function List({todos}) {

  const todoList = todos.map(todo => <li key={i}>{todo}</li>);
  
  return(
    <ul>
      {todoList}
    </ul>
  );
}

export default List;

[2] 새로운 할 일 등록하기

e.preventDefault();
HTMl에서 a태크나 submit태그는 고유의 동작이 있다.
페이지를 이동시키거나 form 안에 있는 input등을 전송하는 동작 등이 있는데, e.preventDefault()가 이러한 동작을 중단시켜주는 역할을 한다.
1) a태그를 눌러도 href 링크를 이동하지 않도록 하고 싶은 경우
2) form안에 submit 역할을 하는 버튼을 눌러도 새로 실행하지 않도록 하고 싶은 경우 (submit은 작동됨)

App.js

// App.js ---------------------------------------------------------//
import React, { Component, useState } from 'react';
import './App.css';

// components
import List from './components/List.jsx';

function App() {

  // useState
  // 등록한 todo들을 담은 배열
  const [todos, setTodos] = useState(['Java 공부하기', 'React 공부하기', '운동하기']);
  // 새로운 todo
  const [newTodo, setNewTodo] = useState();
  

  // changeInputData : newTodo에 input에 입력한 내용을 저장하는 함수
  const changeInputData = (e) => {
    setNewTodo(e.target.value);
  }
  // addTodo
  const addTodo = (e) => {
    e.preventDefault(); // 기본값 form 전송 방지
    setTodos([...todos, newTodo]);
  }

  return(
    <>
      <h1>Todo Application</h1>

      <form action="">
        <input type="text" name="" onChange={changeInputData}/>
        <button onClick={addTodo}>ADD</button>
      </form>

      <List todos={todos} />
    </>
  );
}

export default App;

useEffect Hook

useEffect Hook 공식문서
React Lifecycle에서 마무리 단계, 즉 렌더링 이후에 처리되는 작업들에 대한 로직들을 작성할 때 useEffect라는 Hook을 사용한다.

useEffect Hook 불러오기

import React, { useEffect } from 'react';

useEffect 사용하기 1

괄호 안에 작성하는 콜백함수에는 렌더링 이후 처리할 작업들의 로직을 작성한다.

useEffect( function );

  • function : 렌더링 이후 수행될 작업 (콜백함수)

App.js

// App.js ---------------------------------------------------------//
import React, { Component, useEffect, useState } from 'react';
import './App.css';

// components
import List from './components/List.jsx';

function App() {

  // ---- useState ---- //
  // 등록한 todo들을 담은 배열
  const [todos, setTodos] = useState(['Java 공부하기', 'React 공부하기', '운동하기']);
  // 새로운 todo
  const [newTodo, setNewTodo] = useState();


  // changeInputData : newTodo에 input에 입력한 내용을 저장하는 함수
  const changeInputData = (e) => {
    setNewTodo(e.target.value);
  }
  // addTodo
  const addTodo = (e) => {
    e.preventDefault(); // 기본값 form 전송방지
    setTodos([...todos, newTodo]);
  }

  // ---- useEffect ---- //
  useEffect(() => {
    console.log('새롭게 렌더링 되었습니다.');
  });

  return(
    <>
      <h1>Todo Application</h1>

      <form action="">
        <input type="text" name="" onChange={changeInputData}/>
        <button onClick={addTodo}>ADD</button>
      </form>

      <List todos={todos} />
    </>
  );
}

export default App;

결과를 확인해보면 input 태그에 새로운 것을 입력할 때, ADD 버튼을 눌렀을 때 useEffect의 콜백함수가 실행되는 것을 확인할 수 있다.
새로운 todo가 추가되었을 경우에만, 다시 말해 ADD 버튼을 클릭할 경우에만 콜백함수가 실행되려면 어떻게 해야할까?

useEffect 사용하기 2

특정 props 혹은 state가 변경될 때에만 useEffect가 실행되도록 하고 싶다면, 콜백함수 다음에 두 번째 인자를 넘겨준다.
이 인자는 effect가 종속되어 있는 값의 배열이다.

다음은 todos 배열에 변화가 일어날 경우에만 useEffect가 실행되는 코드이다.

useEffect( function, deps );

  • function : 렌더링 이후 수행될 작업 (콜백함수)
  • deps : 배열 형태, 배열 안에는 검사하고자 하는 특정 값 또는 빈 배열

App.js

// App.js ---------------------------------------------------------//
import React, { Component, useEffect, useState } from 'react';
import './App.css';

// components
import List from './components/List.jsx';

function App() {

  // ---- useState ---- //
  // 등록한 todo들을 담은 배열
  const [todos, setTodos] = useState(['Java 공부하기', 'React 공부하기', '운동하기']);
  // 새로운 todo
  const [newTodo, setNewTodo] = useState();


  // changeInputData : newTodo에 input에 입력한 내용을 저장하는 함수
  const changeInputData = (e) => {
    setNewTodo(e.target.value);
  }
  // addTodo
  const addTodo = (e) => {
    e.preventDefault(); // 기본값 form 전송방지
    setTodos([...todos, newTodo]);
  }

  // ---- useEffect ---- //
  useEffect(() => {
    console.log('새로운 todo가 추가되었습니다.');
  }, [todos]);

  return(
    <>
      <h1>Todo Application</h1>

      <form action="">
        <input type="text" name="" onChange={changeInputData}/>
        <button onClick={addTodo}>ADD</button>
      </form>

      <List todos={todos} />
    </>
  );
}

export default App;

0개의 댓글