💻 결과화면
context API를 이용하여 색상을 선택하면 상자의 색상이 변경되는 기능을 구현해 보았다.
마우스 좌클릭 하면 큰 상자의 색 변경
마우스 우클릭 하면 작은 상자의 색 변경
프로젝트 깃허브 주소 : https://github.com/devuoon/context-tutorial
📒 Context API
context API는 무엇이고 왜 쓰는 것일까?
일반적인 React에서는 props를 통해 데이터를 부모로부터 자식 요소로 전달하는데 이 때 여러 컴포넌트에 전달해야 하는 props의 경우에 과정이 매우 복잡해질 수 있다. 과정이 복잡해진다는 것은 유지 보수가 어렵고 프로젝트가 커질 수록 데이터 관리도 어려워 진다. 이 때 사용하는 것이 context API 이다.
즉, Context API는 리액트 프로젝트에서 전역적으로 사용할 데이터를 손쉽게 관리 하기 위해 사용한다.
전역적으로 관리해야할 데이터에는 어떤 것들이 있을까?
- 현재 로그인한 유저 (사용자 정보)
- 테마 : 사용자가 선택한 테마 (어둡게/밝게)
- 선호하는 언어 : 사용자가 선택한 언어로 컨텐츠를 렌더링
- 장바구니 : 선택한 상품 정보와 수량을 여러 페이지에서 공유
- 앱 설정 : 사용자가 설정한 어플리케이션
- 데이터 로딩 상태 : 데이터를 비동기적으로 불러올 때, 데이터 로딩 상태를 전역으로 관리
- 애플리케이션의 접근 권한 : 사용자별로 접근 권한을 전역적으로 관리 하여 화면 렌더링
📕 프로젝트 해결 과정
1. Consumer가 무엇이고 왜 쓰는 것일까?
const ColorBox = () => {
return (
<ColorContext.Consumer>
{value => (
<div
style={{
width: '64px',
height: '64px',
background: value.color
}}
/>
)}
</ColorContext.Consumer>
);
};
ColorBox라는 컴포넌트를 만들어서 ColorContext 안에 들어 있는 색상을 보여주는 코드를 작성한 것이다.
책에서는 이 과정에서 Consumer라는 컴포넌트를 설명하고 있는데 이 부분에서 잘 이해가 되지 않았다. 관련 문서를 찾아보니 Context.Consumer는 context 변화를 구독하는 컴포넌트이고 Consumer의 자식은 함수여야 한다. 라고 설명 하고 있다. 음.. 여기서 더 부족해서 context를 만들고 consumer까지 오는 과정을 다시 상세히 살펴보니 조금 감이 왔다.
Context.Consumer를 활용하면 데이터를 굳이 props로 전달할 필요 없이 바로 필요한 데이터를 가져와 사용할 수 있다.
이 부분을 이해하고 나니 왜 Consumer의 자식은 함수여야 하는지도 이해가 되었다. 위 'background: value.color' 처럼 value의 값을 바로 가져와서 사용할 수 있고 그러면 context의 데이터가 변경되었을 때 해당 컴포넌트만 리렌더링 될 수 있겠다..! consumer에 대해 조금은 감을 잡을 수 있었다.
2. Provider를 이용해 동적으로 데이터 변경
const ColorContext = createContext({
state: { color: 'black', subcolor: 'red' },
actions: {
setColor: () => {},
setSubcolor: () => {}
}
});
const ColorProvider = ({ children }) => {
const [color, setColor] = useState('black');
const [subcolor, setSubcolor] = useState('red');
const value = {
state: { color, subcolor },
actions: { setColor, setSubcolor }
};
return (
<ColorContext.Provider value={value}>{children}</ColorContext.Provider>
);
};
Provider를 이용해 context 데이터 중 원하는 컴포넌트에만 새로운 값을 받아오도록 했다. useState를 활용해 각각 black과 red로 색상을 초기화 해준 뒤 ColorContext.Provider를 렌더링하며 'value'객체를 'value' 속성으로 전달한다. colorContext의 하위 컴포넌트 들은 'color'와 'subcolor'의 state에 접근하고 'setColor'와 'setSubcolor'의 상태를 업데이트 한다.
3. 컬러 선택 기능 구현
먼저 함수를 구독한다? 라는 개념이 확실하지 않아서 책을 보면서 따라하는데도 어려움이 있었다. 그래서 해당 내용에 대해 개념을 다시 정리해 보았다.
함수를 구독한다는 것은 주로 이벤트 처리나 데이터 변화를 감지하여 미리 정의된 동작을 실행하는 것을 말한다.
그렇다면 현재 프로젝트에서 방금 개념을 다시 살펴보았다.
<ColorConsumer>
{({actions}) => (
<div style={{ display: 'flex' }}>
{colors.map(color => (
<div
key={color}
style={{
background: color,
width: '24px',
height: '24px',
cursor: 'pointer'
}}
onClick={() => actions.setColor(color)}
onContextMenu={e => {
e.preventDefault();
actions.setSubcolor(color);
}}
/>
))}
</div>
)}
</ColorConsumer>
1. 'ColorConsumer'로 'ColorContext'를 구독하여 actions 객체를 가져온다.
ColorConsumer는 ColorContext(전역 데이터를 제공하는 용도로 생성된 context)의 값을 읽어 온다. ColorContext.Provider로 제공한 'value'객체 안의 'actions'라는 키를 가져와 (action객체에는 'setColor'와 'setSubcolor' 를 포함) 사용한다.
2. colors라는 배열을 매핑하면서, 각각의 color에 대해 <div> 요소를 생성한다.
3. 각 <div>는 color 값을 배경색으로 설정되어 있으며, 클릭 또는 오른쪽 클릭(컨텍스트 메뉴) 이벤트를 처리합니다.
4. 클릭 이벤트(onClick)가 발생하면, actions.setColor(color)를 호출하여 color 값을 setColor를 통해 업데이트한다.
5. 오른쪽 클릭 이벤트(onContextMenu)가 발생하면, e.preventDefault()를 사용하여 기본 컨텍스트 메뉴를 막고, actions.setSubcolor(color)를 호출하여 subcolor 값을 setSubcolor를 통해 업데이트한다.
🙌 느낀점
오늘도 새로운 개념들이 많아서 책을 보고 따라하는데도 어려움이 있었다. 역시나 https://legacy.reactjs.org/ 사이트도 참고해보고 다른 책들도 참고하면서 기능 구현을 위해 사용한 개념들을 먼저 익히려고 노력했다. 사실 지금도 이해도는 50%라고 생각한다.. 왜냐하면 다시 처음부터 혼자 하라고 하면 아직 막막하기 때문이다.. 오늘은 context에 대해 배운 첫 날이니까 이정도로 이해하고 계속해서 복습해서 언젠가 혼자서도 코드를 술술 작성할 수 있도록 공부해야겠다..!👍
오공완!
'🎒내가방 > 📒React' 카테고리의 다른 글
[React] Redux(리덕스) 사용해보기 (0) | 2023.08.04 |
---|---|
[React] 뉴스 뷰어 만들기 (0) | 2023.08.01 |