#3 To-Do 앱 최적화 하기 - 2

김민성·2023년 5월 1일
0
post-thumbnail

리액트 Hooks를 이용해서 To-Do 앱을 함수형 컴포넌트로 바꾸기

클래스 컴포넌트에서 함수 컴포넌트로 바꾸는 순서

컴포넌트 자체를 바꾸기

export default class App extends Component { 

이 부분을 아래와 같이 바꾸자.

export default function App() {

그리고 더이상 Component를 extends하지 않기 때문에

import React, {Component} from "react"; 

이 부분을 아래와 같이 바꾼다.

import React from "react"; 

Class 컴포넌트에서는 컴포넌트를 랜더링 하기 위한 render() 안에 return()이 있는 구조지만, 함수형 컴포넌트에서는 render() 없이 바로 return()한다.

  render() { // 클래스 안에서 render를 작성할 수 있다.
    return(
    ...

이 부분을 아래와 같이 render()을 지워준다.

 return(
 ...

State를 useState Hook을 이용해 표현하자.

useState를 사용할 것이기 때문에,

import React, {useState} from "react";

이를 import 해온다.

그리고,

state = {
    todoData : [],
    value: ""
  };

이 부분을 지우고,

 const [todoData, setTodoData] = useState([]);
 const [value, setValue] = useState("");

위의 코드를 넣어준다.

this.state. 모두 지우기

그리고,

let newTodoData = this.state.todoData.filter(data => data.id !== id);
 title: this.state.value,
 this.setState({ todoData: [...this.state.todoData, newTodo ], value:""});
let newTodoData = this.state.todoData.map(data => {
 {this.state.todoData.map((data) => (
value={this.state.value}

위의 코드에서 this.state. 부분을 모두 지워준다.

state를 새로운 값으로 update 해줄 때는

this.setState({value: ""}) ===> setValue("")

this.setState({todoData: newTodoData});

위의 코드를 아래와 같이 바꾼다.

setTodoData(newTodoData)

마찬가지로,

this.setState({ value: e.target.value })

이 코드도 아래와 같이 바꾼다.

setValue(e.target.value)

이 코드는 원래 있던 할 일에 새로운 일을 더해주기 위해 '...' spread operator(전개 구문)을 사용해 객체 하나를 추가해줬는데,

this.setState({ todoData: [...todoData, newTodo ], value:""});

Hooks를 사용할 때에는, Setter에서 이전 State를 가지고 오기 위해서는 인수에 함수를 이용해서 사용할 수 있다.

setTodoData(prev => [...prev, newTodo]);
    setValue("");

함수 및 변수 정의 방법 변경

클래스 컴포넌트에서는 다음과 같이 바로 작성하면 됐지만,

handleClick = (id) => {
    let newTodoData = todoData.filter(data => data.id !== id);
    console.log('newTodoData', newTodoData);
    setTodoData(newTodoData)
  }
 handleChange = (e) => {
    setValue(e.target.value)
  }
handleSubmit = (e) => {
    e.preventDefault(); //페이지가 리로드 되는 것을 막아줌.
getStyle = (completed) => {
    return {
      padding: "10px",
      borderBottom: "1px #ccc dotted",
      textDecoration: completed ?"line-through" :"none"
    }
  }
handleCompleteChange = (id) => {
    let newTodoData = todoData.map(data => {
      if(data.id === id) {
        data.completed = !data.completed; // 반대로
      }
      return data;
    })
    setTodoData(newTodoData);
  }
btnStyle = {
    color: "#fff",
    border: "none",
    padding: "5px 9px",
    borderRadius: "50%",
    cursor: "pointer",
    float: "right"
  }

하지만 함수 컴포넌트에서는 const, class 등을 이용해서 변수나 함수를 정의해야한다.

const handleClick = (id) => {
    let newTodoData = todoData.filter(data => data.id !== id);
    console.log('newTodoData', newTodoData);
    setTodoData(newTodoData)
  }
  const btnStyle = {
    color: "#fff",
    border: "none",
    padding: "5px 9px",
    borderRadius: "50%",
    cursor: "pointer",
    float: "right"
  }

위의 코드처럼 모두 const를 추가해주자.

정의된 함수 및 메소드 사용 방법 변경

클래스 컴포넌트에서는 'this.'을 사용했지만,

 <div style={this.getStyle(data.completed)} key={data.id}>

함수형 컴포넌트에서는 'this.'을 모두 빼주면 된다.

 <div style={getStyle(data.completed)} key={data.id}>

코드에서 'this.' 부분을 모두 삭제해주자.

State vs Props

State

  1. 부모 컴포넌트에서 자녀 컴포넌트로 데이터를 보내는게 아닌 해당 컴포넌트 내부에서.
    -> 데이터를 전달하려면? State으로
    예를 들어서 검색 창에 글을 입력할떄 글이 변하는것은 state를 이용해 바꾸는 것이다.
  2. State 는 변경 가능(mutable)
    3.State 이 변하면 re-render 된다.

Props

  1. Props는 Properties의 줄임말.
  2. Props는 상속하는 부모 컴포넌트로부터 자녀 컴포넌트에 데이터등을 전달하는 방법.
  3. Props는 읽기 전용(immutable)으로 자녀 컴포넌트 입장에서는 변하지 않는다. (변하게 하고자 하면 부모 컴포넌트에서 state를 변경시켜줘야한다.)
profile
다양한 활동을 통해 인사이트를 얻는 것을 즐깁니다. 저 또한 인사이트를 주는 사람이 되고자 합니다.

0개의 댓글

관련 채용 정보