데이터를 전역으로 관리하자 ContextAPI or Redux

API문서

https://ko.reactjs.org/docs/context.html

 

React를 하다보면 여러 컴포넌트를 거쳐서 자료를 전달해야 하거나, 동시에 같은 자료를 사용해야 하는 경우가 생깁니다.

  • Context는 리액트 컴포넌트 간에 어떠한 값을 공유 할 수 있게 해주는 기능입니다.
  • 주로 Context는 전역적(global)으로 필요한 값을 다룰 때 사용합니다.

Props로만 데이터를 전달하는 것은 한계가 있다.

리액트 에서는 일반적으로 컴포넌트에게 데이터를 전달해 주어야 할 때 Props를 통해 전달합니다.

그런데, 이 컴포넌트의 형태가 복잡하다면 어떻게 될까요?

 

 

 

 

https://velopert.com/3606

G에서 변경된 값을 J로 가져가려면 Root를 거쳐 J로 돌아가야 합니다.

G값을 핸들링하는 함수 또한 Root에서 선언 해야합니다.

Props를 통해 핸들링 함수를 자식 컴포넌트(JS는 변수로 함수를 전달가능) 로 전달해줘야 합니다.

 

이런 문제는

Context API 또는 Redux를 사용하여 공통(전역)으로 사용하는 데이터를 외부에서 편리하게 사용할 수 있습니다.

 

 

 

 

ConextAPI 사용방법

 

createContext() 훅 

  • ContextAPI를 생성합니다.
const 사용할이름 = createContext(초기값)

 

provider와 consumer

Provider Component 부모에서 사용 Context의 변화를 하위 컴포넌트에 알린다.
Consumer Component 자식에서 사용 부모 Component중 가장 가까운 Provider가 전달하는 데이터를 받아서 사용한다.

 

구현순서

  1. ContextAPI를 생성한다.
  2. 자식 컴포넌트에서는 Consumer를 이용해서 데이터 받기
  3. 부모 컴포넌트에서는 Provider를 사용해서 value값을 제어한다.

ContextAPI.js 생성

import { createContext } from "react";

//컨텍스트의 기본상태 지정
const ColorContext = createContext({color : 'red'})

export default ColorContext; //외부에서 사용하도록 export

 

ColorComponent.js 안에서 Consumer의 사용

  • Context 변화를 사용하는 React 컴포넌트입니다. 이 컴포넌트를 사용하면 함수 컴포넌트안에서 Context를 사용 할 수 있습니다.
  • Context.Consumer의 자식은 함수여야합니다. (첫번째 매개변수에서 context값을 얻습니다)
  • return에 화면에 렌더링할 JSX를 만듭니다.
//...
const ColorComponent = () => {

    return (
        <ColorContext.Consumer>
            {/* ColorContext 안에 Consumer를 사용하고 
            JSX자리에 함수로 return을 처리하는 구문을 사용함 */}
            {
                (value) => (
                    <div style={{background: value.color}}> 
                        ConTextAPI사용<br/>
                        값: {value.color}
                    </div>
                )
            }
        </ColorContext.Consumer>

    )

}

export default ColorComponent;

App.js 안에서 Provider의 사용

  • Context에 포함된 React 컴포넌트인 Provider는 context를 사용하는 컴포넌트들에게 context의 변화를 알리는 역할을 합니다.
  • Provider 컴포넌트는 value prop을 받아서 이 값을 하위에 있는 컴포넌트에게 전달합니다.
  • Provider 하위에서 context를 사용하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.
//...
const App = () => {

    return (
        <ColorContext.Provider value={{color: 'green'}}>
            <ColorComponent/>
        </ColorContext.Provider>

    )
}

export default App;

 


Provider와 Consumer를 독립적으로 분리하기

 

  • ContextAPI는 전역으로 사용할 값이기 때문에 파일을 독립적으로 분리해서 작성하도록 변경합니다.
  • 하위 컴포넌트에서는 훅을 이용해서 더욱 편리하게 사용할 수 있습니다.

 

useContext() 훅

  • 컴포넌트에서 context API를 편하게 사용하는 훅입니다
  • 리턴은 객체이고 첫번째 값은 상태값, 두번째는 값을 저장하는 setter를 가진 객체를 반환합니다.
const {state, action} = useContext(컨택스트API객체)

 

구현순서

  1. ContextAPI2.js 생성 (Provider재정의, Consumer를 외부로 export)
  2. App.js에서 Provider감싸기
  3. A.js 훅 으로 컨텍스트 사용하기

ContextAPI2.js 에서는...

import { createContext, useState } from "react";


//1. 초기값 설정
const UserContext = createContext({
    state : {id: 'aaa', name : 'bbb'},
    action : {
        setUser : () => {}
    }
});

//2. Provider컴포넌트 재정의
//매개값의 이름은 반드시 children으로 구조분해할당 합니다.
//useState를 활용해서 데이터를 관리합니다.
const UserProvider = ({children}) => {
    const [user, setUser] = useState({id: 'aaa', name: 'bbb'});
    const value = {
        state : user,
        action : {setUser}
    }
    //Provider 반환
    return (
        <UserContext.Provider value={value}>{children}</UserContext.Provider>
    )
}

//3. 외부에서 사용가능 하도록 consumer, provider 반환
const UserConsumer = UserContext.Consumer;
export {UserProvider, UserConsumer}

export default UserContext;

App.js에서는...

 

import A from "./component3/A";
import B from "./component3/B";
import { UserProvider } from "./contexts/ContextAPI2";

const App = () => {

    return (
        <UserProvider>
            <A/>
            <B/>
        </UserProvider>

    )
}

export default App;

A.js 그리고 B.js에서는..

import { useContext, useRef } from "react";
import UserContext, { UserConsumer } from "../contexts/ContextAPI2";

const A = () => {
    //useRef훅
    const input1 = useRef(null);
    const input2 = useRef(null);

    //useContext훅 - 을 이용해서 값 조회 or 값 변경
    //Context API를 훅으로 사용
    const {state, action} = useContext(UserContext);

    const handleClick = () => {
        action.setUser({id: input1.current.value,
                       name: input2.current.value});
        
        input1.current.value = '';               
        input2.current.value = '';               
    }

    return (
        <div>
            <h3>A컴포넌트</h3>
            <input type="text" ref={input1}/>
            <input type="text" ref={input2}/>
            <button onClick={handleClick}>데이터변경</button>

            <div>
                {state.id}<br/>
                {state.name}<br/>
            </div>

        </div>
    )
}

export default A;

'Front-End > React' 카테고리의 다른 글

11. firebase에 react배포하기  (0) 2023.01.04
9. Ajax로 외부 데이터 통신하기  (0) 2022.12.29
8. React라우터  (0) 2022.12.28
7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26

+ Recent posts