[React] Context API

Dorong·2023년 6월 29일
0

React

목록 보기
25/29
post-thumbnail

✅ 기본 개념

  • 리액트 App은 컴포넌트 간에 데이터를 props로 전달
  • 이는 데이터를 주고받는 구조가 복잡해지면 유지보수성이 낮아지는 등 단점 발생
  • 이를 더욱 편하게 하는 전역 상태 관리 작업을 가능하게 해줌
  • 보통 Redux나 MobX 같은 상태 관리 라이브러리 많이 사용하지만,
  • 리액트 v16.3 업데이트 이후 Context API가 많이 개선되어 쉽게 사용 가능


✅ Context 사용해보기

🔸 createContext - Context 만들기

  • createContext 함수를 사용해 새 Context를 만들고 기본 상태 지정
import {createContext} from 'react';

const SampleContext = createContext({ greet : 'Hi' })

export default SampleContext;

🔸 Consumer

  • 값을 props로 받아오지 않고 생성한 Context 안에 있는 Consumer로 값 조회
import SampleContext from '../contexts/sampleContext';

const SampleComponent = () => {
    return (
        <SampleContext.Consumer>
            {
                value => (
                    <div>{value.greet}</div>
                )
            }
        </SampleContext.Consumer>
    )
}

🔸 Provider

  • Provider를 사용해 Context의 value를 변경할 수 있음
// App.js에서
import SampleComponent from '';
import SampleContext from '';
const App = () => {
    return(
        <SampleContext.Provider value = {{greet : 'hello'}}>
            <div>
                <SampleComponent/>
            </div>
        </SampleContext.Provider>

    )
}
  • createContext에서 넣어준 기본값은 Provider를 사용하지 않았을 때만 사용됨
    => Provider는 사용했는데 value 넣지 않으면, 기본값도 사용하지 않으므로 오류 발생


✅ 여러 값 관리하는 동적 Context

🔸 Context 수정해보쟈

  • Context의 value에는 상태 값 뿐만 아니라 함수 전달도 가능
import {createContext, useState} from 'react';

const SampleContext = createContext({
    state : { greet : 'Hi', name : 'Yu' },
    actions : {
        setGreet : () => {},
        setName : () => {}
    }
})

const SampleProvider = ({children}) => {
    const [greet, setGreet] = useState('Hi');
    const [name, setName] = useState('Yu');

    const value = {
        state : { greet, name },
        actions : { setGreet, setName}
    };

    return (
        <SampleContext.Provider value = {value}> {children} </SampleContext.Provider>
    )
};

// const SampleConsumer = SampleContext.Consumer와 같은 의미
const { Consumer : SampleConsumer } = SampleContext;

export { SampleProvider, SampleConsumer }

export default SampleContext;
  • Provider의 value에서 상태는 state, 업데이트 함수는 actions로 묶어 전달
  • 반드시 묶어줄 필요는 없으나, state, actions를 분리해두면 다른 컴포넌트에서 Context 값 사용 시 편리
  • createContext의 기본값은 실제 Provider의 value에 넣는 객체의 형태와 일치시켜주는 게 좋음

🔸 여러 값 Context 사용해보기

  • App.js에서 SampleContext.Provider => SampleProvider로 변경
import SampleComponent from '';
import {SampleProvider} from '';
const App = () => {
    return(
        <SampleProvider>
            <div>
                <SampleComponent/>
            </div>
        </SampleProvider>

    )
}
  • SampleComponent에서
import {SampleConsumer} from '../contexts/sampleContext';

const SampleComponent = () => {
    return (
        <SampleConsumer>
            {
                value => (
                    <>
                        <div>{value.state.greet}</div>
                        <div>{value.state.name}</div>
                    </>
                )
            }
        </SampleConsumer>

        /* 이렇게도 가능
        <SampleConsumer>
            {
                ({state}) => (
                    <>
                        <div>{state.greet}</div>
                        <div>{state.name}</div>
                    </>
                )
            }
        </SampleConsumer>
        */
    )
}

🔸 동적 Context 사용해보기

// 새로 생성한 SelectName.js
import {SampleConsumer} from '';

const names = ['Kim','Lee','Park','Ma','Jung'];

const SelectName = () => {
    return (
        <div>
            <SampleConsumer>
                {({actions}) => (
                    <div style={{display : 'flex'}}>
                        {
                            names.map( name => (
                                <div key = {name} onClick = {() => actions.setName(name)}>
                                    {name}
                                </div>
                            ))
                        }
                    </div>
                )}
            </SampleConsumer>
        </div>
    )
}

// App.js
...
const App = () => {
    return(
        <SampleProvider>
            <div>
                <SelectName/>
                <SampleComponent/>
            </div>
        </SampleProvider>

    )
}


✅ useContext Hook 사용하기

  • 함수형 컴포넌트에서는 Consumer 대신 useContext Hook을 사용할 수 있음
  • SampleComponent에서
import SampleContext from '';
import { useContext } from 'react';

const SampleComponent = () => {
	const {state} = useContext(SampleContext);
	
    return (
        <div>
 			<div>{state.greet}</div>
			<div>{state.name}</div>
        </div>
    )
}
profile
🥳믓진 개발자가 되겠어요🥳

0개의 댓글