React usestate, useContext Hooks 및 Context API를 사용한 글로벌 상태 관리.



react가 16.3.0 릴리스에서 안정적인 버전의 컨텍스트 API를 발표한 지 꽤 오래되었습니다. Redux와 같은 라이브러리 이전에는 MobX가 상태 관리에 사용되었습니다. 이 게시물에서는 컨텍스트 API 및 Hooks를 사용하여 구성 요소의 상태를 관리하는 방법에 대한 몇 가지 예를 들어 설명하겠습니다.

다음과 같은 매우 간단한 시나리오부터 시작하겠습니다.

컨텍스트 API의 간단한 사용 사례

ChildComponentA라는 자식이 있는 Basecomponent가 있고 여기에 ChildComponentB라는 자체 자식이 있습니다. 이제 우리는 BaseComponent에서 ChildComponentB로 const를 전달하려고 합니다. BaseComponent에서 ChildComponentA로 그리고 ChildComponentB로 const를 prop으로 전달하여 쉽게 수행할 수 있습니다. 옳게 보일 수 있지만 문제가 있습니다. 10개가 있으면 어떻게 됩니까? BaseComponent와 ChildComponentB 사이의 자식 구성 요소. 이제 BaseComponent에서 ChildComponentB에 도달할 때까지 모든 자식 구성 요소를 통해 소품을 드릴다운해야 합니다. 이것은 분명히 올바른 방법이 아닙니다. 이 문제를 피하기 위해 우리는 Context API를 사용합니다.

컨텍스트 API는 어떻게 작동합니까?



Context API가 작동하는 방식은 React.createContext()를 사용하여 컨텍스트를 만들고 구성 요소 트리의 맨 위에 컨텍스트를 제공한 후 를 사용하여 구성 요소 트리의 맨 위에 제공하는 것입니다. 해당 트리 내부의 모든 수준에서 액세스할 수 있습니다. 그런 다음 또는 useContext 후크를 사용하여 해당 값을 사용할 수 있습니다. 복잡하게 들릴 수 있지만 아래 예제를 보면 간단하다는 것을 알 수 있습니다.

예시 1 (context 값 소비)



이 예는 세 가지 구성 요소가 있는 위의 시나리오에 대한 것입니다.

import React, { useContext } from 'react'

const FruitContext = React.createContext()

const BaseComponent = () => {
  return (
    <FruitContext.Provider value={'Apple'}>
        <ChildComponentA />
    </FruitContext.Provider>
  )
}

const ChildComponentA = () => {
  return (
    <div>
      <ChildComponentB />
    </div>
  )
}

const ChildComponentB = () => {
  const fruitName = useContext(FruitContext)

  return (
    <h1>
      {fruitName}
    </h1>
  )
}

export { BaseComponent }

를 사용하는 대신 이와 같이 useContext 후크를 사용할 수도 있습니다.

const ChildComponentB = () => {
  const fruitName = useContext(Context)

  return (
    <h1>{fruitName}</h1>
  )
}

예 2(여러 컨텍스트 사용)

이 예제는 단일 컨텍스트 대신 여러 컨텍스트를 사용한다는 점을 제외하면 이전 예제와 같습니다. BaseComponent에서 이름과 나이라는 두 컨텍스트에 대한 값을 제공한 다음 이전과 같이 ChildComponentB에서 해당 값을 사용했습니다.

import React, { useContext } from 'react'

const Name = React.createContext()
const Age = React.createContext()

const BaseComponent = () => {
  return (
    <Name.Provider value={'Mateen'}>
      <Age.Provider value={'20'}>
        <ChildComponentA />
      </Age.Provider>
    </Name.Provider>
  )
}

const ChildComponentA = () => {
  return (
    <div>
      <ChildComponentB />
    </div>
  )
}

const ChildComponentB = () => {
  const name = useContext(Name)
  const age = useContext(Age)

  return (
    <h1>
      I am {name} and I am {age} years old.
    </h1>
  )
}

export { BaseComponent }

예 3(useState 후크가 있는 컨텍스트 API)



상태 관리를 수행하지 않았다고 생각해야 합니다. 이 예제에서는 Context API를 useState 후크와 결합하여 앱의 상태를 관리합니다. 이제 컨텍스트 값이 업데이트될 때마다 이를 사용하는 모든 구성 요소가 다시 렌더링되어 모든 구성 요소의 상태를 동기화합니다. useState 후크에 익숙하지 않은 경우 다음 예를 고려하십시오.

Const [state, setState] = useState(initial value)

State is the variable that is been assigned the value “initial State” and setState is a callback function to update the value of our state variable. To update the value of our state variable we must call setState and whenever the value of state variable changes every component that uses it re renders. This is enough for now to understand this useState hook.

useState() hook



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

const Theme = React.createContext()

const BaseComponent = () => {
  const [theme, setTheme] = useState('Light')

  const toggleTheme = () => {
    setTheme(theme === 'Light' ? 'Dark' : 'Light')
  }

  return (
    <Theme.Provider value={theme}>
      <ChildComponentA />
      <button onClick={toggleTheme}>Change Theme</button>
    </Theme.Provider>
  )
}

const ChildComponentA = () => {
  return (
    <div>
      <ChildComponentB />
    </div>
  )
}

const ChildComponentB = () => {
  const theme = useContext(Theme)

  return (
    <h1>
      current theme is {theme}.
      </h1>
    )
}

export { BaseComponent }

반응 테마에 대한 자세한 내용은 this 게시물을 참조하세요.

예시 4 (컨텍스트 값으로 콜백 함수를 전달하여 글로벌 상태 관리)



이 예제는 전역 상태 관리 범주에 속하므로 약간 복잡합니다. 구성 요소의 상태를 전역적으로 관리하는 가장 쉬운 방법 중 하나(공급자 내부의 구성 요소 상태를 업데이트하려면)는 콜백 함수를 컨텍스트 값으로 전달하여 상태 변수를 업데이트하려는 모든 곳에서 호출할 수 있도록 하는 것입니다. . 이 예에서는 영화 이름과 감독 이름이 있는 영화 목록이 있습니다. 목록에 영화를 더 추가하고 목록에 있는 영화 수를 가져올 수 있으며 목록에 영화를 추가할 때마다 구성 요소가 UI를 업데이트합니다.

Movie Provider는 초기 목록을 보유하고 있으며 구성 요소를 이 공급자로 래핑할 때 영화 목록에 액세스하고 업데이트할 수 있습니다. 헤더 구성 요소는 목록에 있는 영화의 수를 표시합니다. 영화 추가 구성 요소는 양식을 사용하여 영화를 목록에 추가합니다. 영화 구성 요소는 UI에 영화 목록을 표시합니다.

MovieProvider.js



import React, { useState } from 'react'

export const MovieContext = React.createContext();

export const MovieProvider = (props) => {
  const [movies, setMovies] = useState([
    {
      name: 'Wreck it Ralph',
      director: 'Rich Moore',
      id: 432
    },
    {
      name: 'The Incredibles',
      director: 'Brad Bird',
      id: 234
    },
    {
      name: 'Despicable me',
      director: 'Pierre Coffin',
      id: 542
    }
  ])

  return (
    <MovieContext.Provider value={[movies, setMovies]} >
      {props.children}
    </MovieContext.Provider>
  )

}

AddMovie.js



import React, { useContext, useState } from 'react'
import { MovieContext } from './MovieProvider'

const AddMovie = () => {
  const [movies, setMovies] = useContext(MovieContext)

  const [movieName, setMovieName] = useState('')
  const [directorName, setDirectorName] = useState('')

  const handleSubmit = event => {
    event.preventDefault()
    const rand = Math.random()
    setMovies(movies => [
      ...movies,
      { name: movieName, director: directorName }
    ])
  }

  return (
    <form onSubmit={handleSubmit} style={{ padding: '10px' }}>
      <input
        type='text'
        value={movieName}
        placeholder='Enter Movie Name'
        onChange={e => setMovieName(e.target.value)}
      />
      <input
        type='text'
        value={directorName}
        placeholder='Enter Director Name'
        onChange={e => setDirectorName(e.target.value)}
      />
      <input type='submit' value='Add Movie' />
    </form>
  )
}

export default AddMovie

Header.js



import React, { useContext } from 'react'
import { MovieContext } from './MovieProvider'

const Header = () => {

  const header = {
    paddingLeft: '15px',
    backgroundColor: 'blue',
    color: 'white',
    fontStyle: 'light',
    width: '100%',
    height: '50px',
  }

  const [movies] = useContext(MovieContext)

  return (
    <div style={header}>
      <h1>Number of movies {movies.length}</h1>
    </div>
  )
}

export default Header

Movies.js



import React, { useContext } from 'react'
import { MovieContext } from './MovieProvider'

const Movies = () => {
  const [movies] = useContext(MovieContext)

  return (
    <div>
      {movies.map(movie => (
        <div key={movie.id} style={{padding:'10px'}}>
          Movie Name:{' '}
          <span style={{ color: 'red', fontStyle: 'italic' }}>
            {movie.name}
          </span>{' '}
          | Director Name{' '}
          <span style={{ color: 'red', fontStyle: 'italic' }}>
            {movie.director}
          </span>
        </div>
      ))}
    </div>
  )
}

export default Movies

App.js



import React from 'react'
import {MovieProvider} from './components/MovieProvider'
import Header from './components/Header';
import Movies from './components/Movies'
import AddMovie from './components/AddMovie'

function App() {
  return (
    <MovieProvider>
      <Header />
      <AddMovie />
      <Movies />
    </MovieProvider>
  )
}

export default App

최종 출력은 다음과 같습니다.

최종 출력

게시물 State Management with Context Api, UseState and useContext hooks – React CreateContext.Mild Dev에 처음 나타났습니다.

많은 도움이 되니 좋아요, 공유, 팔로우 잊지마세요. 질문이 있으시면 의견 섹션에 알려주십시오.

좋은 웹페이지 즐겨찾기