프론트엔드 개발자의 기록 공간

[React] React(4) 본문

프로그래머스 데브코스_FE/TIL

[React] React(4)

[리우] 2022. 1. 23. 14:06

❗❗  데브코스 52일차 (10.12)

오늘은 상태관리 라이브러리 중 하나인 Context API에 대해 다룬다.

바로 본론으로 고고!

 

✅ Context API

React에서 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달할 때 props을 통해 전달이 된다.
반대의 과정에서는 props를 타고 올라가야 한다. 만약 컴포넌트가 무수히 많다면 여러 컴포넌트들을 거쳐가게 된다.
이 과정에서 계속 props로만 전달받게 되면 Prop Drilling 문제가 생기게 된다.
Prop Drilling을 해결하기 위해 Redux, Recoil, Mobx, Context API 등이 존재한다.
이번에는 React 라이브러리에서 기본으로 제공되는 Context API에 대해 다뤄 볼 예정이다.

 

상태 관리 춘추전국시대라고 할 정도로 엄청 많다.

상태 관리에 대해 조금 더 이해하고 싶다면 이전 Vue(5)를 읽으면 도움이 될 것이다.

상태 관리 개념은 동일하니깐!

 

 

Context API 예시

Context API는 Provider와 Consumer 개념이 사용된다.

  • Context Provider : 데이터를 제공하는 자
  • Context Consumer : 데이터를 제공받는 자

동작 원리는 간단하다.
데이터는 Provider가 관리하고 Consumer는 받아서 처리만 해주면 된다.
데이터가 바뀌면 이벤트를 통해 Provider를 업데이트해주고 Provider가 업데이트되면
Consumer은 반응형으로 인해 다시 연산을 하고 컴포넌트는 다시 렌더링 된다.
위의 과정을 통해 데이터를 상태 관리를 하게 된다.

 

하지만 Context API를 무분별하게 사용할 시, 문제가 있으므로 적절하게 필요한 곳에서만 사용해야 한다.

  • 성능 이슈가 발생 : Provider 업데이트되면 Consumer과 관련된 모든 컴포넌트가 다시 렌더링 되기 때문이다. 물론 어느 정도 최적화가 가능하지만 꼭 필요한 곳에서만 사용하는 것을 권장한다.

 

🟦 Context Provider 사용법

tasks 배열에 값을 추가하는 Provider

import { createContext, useContext, useState } from 'react'

//Context 만들기
const TaskContext = createContext()

//context 객체(React.createContext에서 반환된 값)을 받아 그 context의 현재 값을 반환
//즉 Consumer에서 편의성을 위해 사용
export const useTasks = () => useContext(TaskContext)

const TaskProvider = ({ children }) => {
  const [tasks, setTasks] = useState([])

  const addTask = (content) => {
     setTasks([
      ...tasks,
      {
        content,
      },
    ])
  }


  return (
			//Consumer에서 사용할 함수, 변수 등을 정의
    <TaskContext.Provider value={{ tasks, addTask }}>
      {children}
    </TaskContext.Provider>
  )
}

export default TaskProvider

🟦 Context Consumer 사용법

사용자가 입력한 Text 값을 Button 클릭 시, Provider의 addTask 함수를 사용하여 데이터를 추가하는 Consumer 예시

import { useState } from 'react'
import { useTasks } from '../contexts/TaskProvider'
const NewTaskForm = (props) => {
  const [task, setTask] = useState('')
  //Provider의 addTask함수 불러오기
  const { addTask } = useTasks()

  const handleSubmit = (e) => {
    e.preventDefault()
    //Provider함수를 사용하여 task 추가
    addTask(task)
    setTask('')
  }

  return (
    <Form {...props} onSubmit={handleSubmit}>
      <Input
        type="text"
        value={task}
        onChange={(e) => setTask(e.target.value)}
      />
      <SubmitButton>Add</SubmitButton>
    </Form>
  )
}

Provider에 정의된 tasks 배열을 가져와서 사용하는 Consumer 예시

 

import { useTasks } from '../contexts/TaskProvider'
import Task from './Task'

const TaskList = () => {
  const { tasks } = useTasks()
  return (
    <div>
      {tasks.map((item) => (
        <li
          key={item.id}
          id={item.id}
          content={item.content}
          complete={item.complete}
        ></li>
      ))}
    </div>
  )
}

 

그 외에 Provider, Consumer를 사용하는 제일 최상단 컴포넌트 (ex. App 컴포넌트)에서
Provider를 정의한 컴포넌트로 감싸서 사용해야 한다.

import NewTaskForm from './components/NewTaskForm'
import TaskList from './components/TaskList'
import TaskProvider from './contexts/TaskProvider'

function App() {
  return (
    <TaskProvider>
      <NewTaskForm></NewTaskForm>
      <TaskList></TaskList>
    </TaskProvider>
  )
}

 

👨‍💻 React 상태 관리를 처음 학습할 때, 상태 관리에 대해 잘 모른 상황에서 Redux를 학습했다. 그 당시에는 무슨 소리인지, 또 어떻게 사용해야 하는지 잘 이해가 가지 않았는데 이번 계기를 통해 확실히 개념과 사용법을 알아갔다. 아직도 직접 정의해서 사용하려면 많은 연습이 필요하겠지만 유용한 강의였다.

728x90

'프로그래머스 데브코스_FE > TIL' 카테고리의 다른 글

[React] React(6)  (0) 2022.01.26
[React] React(5)  (0) 2022.01.24
[React] React(3)  (0) 2022.01.20
[React] React(2)  (0) 2022.01.18
[React] React(1)  (0) 2022.01.17
Comments