이번에 설명해볼 내용은 Context API에 관해서입니다.
redux와 같은 상태 관리를 위한 라이브러리입니다. react의 내장 라이브러리로서 사용 가능합니다.
create-react-app으로 리액트 프로젝트를 하나 생성해줍시다. 후에
import React, {createContext, useState} from 'react';
const ColorContext = createContext({color:'pink'});
export default ColorContext;
위와 같은 js 파일을 하나 생성합니다.
createContext는 초기값 설정이라고 보시면 됩니다. json 타입으로 color를 pink로 초기화해주었습니다.
import React from 'react';
import ColorContext from './Color';
const App=()=>{
return(
<div>
<ColorContext.Consumer>
{ value=>(<div style={{width:'60px' ,height:'50px' , background: value.color }}/>)}
</ColorContext.Consumer>
</div>
)
}
export default App;
간단하게 App에다 바로 넣어주었습니다. createContext의 Consumer를 사용하면
children처럼 컴포넌트 내부에서 value값을 가져올 수 있습니다. 하지만
중괄호 하나를 더생성하고 컴포넌트를 불러주어 그 안에 value.color값을 넣어주었습니다.
이런 패턴을 Render Props라고 합니다.
쉽게 생각하면 전역 변수를 가져와서 사용한 것입니다.
여기서 초기값을 변경하는 법이 있습니다.
import React from 'react';
import ColorContext from './Color';
const App=()=>{
return(
<div>
<ColorContext.Provider value={{color:'green' }}>
<ColorContext.Consumer>
{ value=>(<div style={{width:'60px' ,height:'50px' , background: value.color }}/>)}
</ColorContext.Consumer>
</ColorContext.Provider>
</div>
)
}
export default App;
Provider를 이용하는 것입니다. 전부 createContext를 기준으로 한 컴포넌트로 사용되는 것을 볼 수 있습니다.
Provider를 사용하면 Context에 초기값이 있다면 대신하고 없으면 채워주는 컴포넌트입니다.
벌써 사용법과 변경법을 끝냈습니다. 아주 간단하고 이해하기 쉽게 적었기 때문에 쓸모없어 보이고
감이 오지 않을 수 있습니다.
그런 분들을 위해 밑의 3가지 파일을 준비했습니다.
첫 번째 컴포넌트입니다.
import React from 'react'
import {ColorConsumer} from './Color'
const ColorBox =()=>{
return (
<ColorConsumer>
{ ({state}) =>(
<>
<div style={{ width:'64px' , height:'64px', background: state.color}} />
<div style={{ width:'32px' , height:'32px', background: state.subcolor}} />
</>
)}
</ColorConsumer>
);
}
export default ColorBox;
ColorBox라는 보여주기 전용 컴포넌트를 작성합니다.
ColorConsumer는 아래와 같은 코드 중 하나를 선언을 했기 때문에 사용 가능합니다.
const ColorConsumer = ColorContext.Consumer; //아래의 코드와 같음
const {Consumer: ColorConsumer} = ColorContext; //위의 코드와 같음
즉 ColorContext.Consumer 컴포넌트에서 value가 아닌 state 기준으로 보여줍니다.
2번째 컴포넌트입니다.
import React, {createContext, useState} from 'react';
const ColorContext = createContext({
state:{color: 'black' , subcolor: 'red'},
action: {
setColor: ()=>{},
setSubcolor:()=>{}
}
});
const ColorProvider = ({children})=>{
const [color , setColor] = useState('black');
const [subcolor , setSubcolor] = useState('red');
const value = {
state:{color, subcolor},
action: {setColor , setSubcolor}
};
return(
<ColorContext.Provider value={value} >{children}</ColorContext.Provider>
);
};
const {Consumer: ColorConsumer} = ColorContext;
export {ColorProvider, ColorConsumer};
export default ColorContext;
useState를 사용해줍니다. 초기값을 createContext로 설정해준 다음
하단부에 Provider를 바로 만들어줍니다. value를 그냥 써도 되지만 redux처럼 구분 지어줘서 사용하기 위해
value내에 state와 action을 나눠줬습니다.
import React, {useState} from 'react'
import ColorBox from './ColorBox';
import {ColorProvider , ColorConsumer} from './Color'
const App =()=>{
return (
<div>
<ColorProvider>
<div>
<ColorBox />
</div>
<ColorConsumer>
{ ({action})=>(<button onClick={()=>{action.setColor('blue') }}>asdf</button>)}
</ColorConsumer>
</ColorProvider>
</div>
);
}
export default App;
마지막으로 출력하는 부분입니다. App 컴포넌트에 종합하는 부분입니다. 단,
action을 이용하여 useState를 사용해주기 때문에 값을 변경 가능합니다. 이로서 redux와 비슷한 기능을
간단하게 사용할 수 있는 것입니다. 간편한 기능일 경우 redux와 성능 편차가 크지 않습니다.
hooks처럼 context도 발전 가능성이 높으니 짚고 넘어가면 좋다고 생각합니다.