일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Java
- 어윈 사용법
- NestedFor
- 사용자예외클래스생성
- EnhancedFor
- 예외미루기
- exception
- cursor문
- oracle
- 집합_SET
- 다형성
- 오라클
- abstract
- 추상메서드
- 예외처리
- 인터페이스
- 한국건설관리시스템
- 자바
- 컬렉션 타입
- 환경설정
- 생성자오버로드
- 제네릭
- GRANT VIEW
- 대덕인재개발원
- 메소드오버로딩
- 객체 비교
- 컬렉션프레임워크
- 자동차수리시스템
- 참조형변수
- 정수형타입
- Today
- Total
거니의 velog
(2) Context API 2 본문
3. 동적 Context 사용하기
* 지금까지 배운 내용으로는 고정적인 값만 사용할 수 있다. 이번에는 Context의 값을 업데이트해야 하는 경우 어떻게 해야 하는지 알아보자.
(1) Context 파일 수정하기
* Context의 value에는 무조건 상태 값만 있어야 하는 것은 아니다. 함수를 전달해 줄 수도 있다.
* 기존에 작성했던 ColorContext의 코드를 다음과 같이 수정해 보자. 이번에 코드를 작성한 후 저장하면 오류가 발생할 텐데, 해당 오류는 나중에 수정할 것이므로 걱정하지 말자.
[color.js]
import { createContext, useState } from "react";
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>
);
};
// const ColorConsumer = ColorContext.Consumer와 같은 의미
const { Consumer: ColorConsumer } = ColorContext;
// ColorProvider와 ColorConsumer 내보내기
export { ColorProvider, ColorConsumer };
export default ColorContext;
* 위 파일에서 ColorProvider라는 컴포넌트를 새로 작성해 주었다. 그리고 그 컴포넌트에서는 ColorContext.Provider를 렌더링하고 있다. 이 Provider와 value에는 상태는 state로, 업데이트 함수는 actions로 묶어서 전달하고 있다. Context에서 값을 동적으로 사용할 떄 반드시 묶어 줄 필요는 없지만, 이렇게 state와 actions 객체를 따로따로 분리해 주면 나중에 다른 컴포넌트에서 Context의 값을 사용할 때 편하다.
* 추가로 createContext를 사용할 때 기본값으로 사용할 객체도 수정했다. createContext의 기본값은 실제 Provider의 value에 넣는 객체의 형태와 일치시켜 주는 것이 좋다. 그렇게 하면 Context 코드를 볼 때 내부 값이 어떻게 구성되어 있는지 파악하기도 쉽고, 실수로 Provider를 사용하지 않았을 때 리액트 애플리케이션에서 에러가 발생하지 않는다.
(2) 새로워진 Context를 프로젝트에 반영하기
* 코드를 다 작성했으면 App 컴포넌트에서 ColorContext.Provider를 ColorProvider로 대체하자.
[App.js]
import React from "react";
import ColorBox from "./components/ColorBox";
import { ColorProvider } from "./contexts/color";
const App = () => {
return (
<ColorProvider>
<div>
<ColorBox />
</div>
</ColorProvider>
);
};
export default App;
* ColorBox도 마찬가지로 ColorContext.Consumer를 ColorConsumer로 변경하자. 또한, 사용할 value의 형태도 바뀌었으니 이에 따른 변화를 다음과 같이 반영시켜 보자.
[ColorBox.js]
import React from "react";
import { ColorConsumer } from "../contexts/color";
const ColorBox = () => {
return (
<ColorConsumer>
{(value) => (
<>
<div
style={{
width: "64px",
height: "64px",
backgroundColor: value.state.color,
}}
/>
<div
style={{
width: "32px",
height: "32px",
backgroundColor: value.state.subColor,
}}
/>
</>
)}
</ColorConsumer>
);
};
export default ColorBox;
* 위 코드에서 객체 비구조화 할당 문법을 사용하면 다음과 같이 value를 조회하는 것을 생략할 수도 있다.
import React from "react";
import { ColorConsumer } from "../contexts/color";
const ColorBox = () => {
return (
<ColorConsumer>
{({ state }) => (
<>
<div
style={{
width: "64px",
height: "64px",
backgroundColor: state.color,
}}
/>
<div
style={{
width: "32px",
height: "32px",
backgroundColor: state.subColor,
}}
/>
</>
)}
</ColorConsumer>
);
};
export default ColorBox;
* 코드를 다 작성했다면 브라우저를 확인해 보자.
* 검정색 정사각형과 빨간색 정사각형이 잘 보이는가?
(3) 색상 선택 컴포넌트 만들기
* 이번에는 Context의 actions에 넣어 준 함수를 호출하는 컴포넌트를 만들어 보자. components 디렉터리에 SelectColors.js 라는 파일을 생성하여 다음 코드를 작성해 보자. 지금은 Consumer를 사용하지 않고 UI만 준비해 보자.
import React from "react";
const colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
const SelectColors = () => {
return (
<div>
<h2>색상을 선택하세요</h2>
<div style={{ display: "flex" }}>
{colors.map((color) => (
<div
key={color}
style={{
backgroundColor: color,
width: "24px",
height: "24px",
cursor: "pointer",
}}
/>
))}
</div>
<hr />
</div>
);
};
export default SelectColors;
* 다 작성했으면 이 컴포넌트를 App 컴포넌트에서 ColorBox 위에 렌더링 하자.
import React from "react";
import ColorBox from "./components/ColorBox";
import { ColorProvider } from "./contexts/color";
import SelectColors from "./components/SelectColors";
const App = () => {
return (
<ColorProvider>
<div>
<SelectColors />
<ColorBox />
</div>
</ColorProvider>
);
};
export default App;
* 브라우저에 다음과 같이 무지개 색상으로 이루어진 정사각형이 나타나는가?
* 이제 해당 SelectColors 에서 마우스 왼쪽 버튼을 클릭하면 큰 정사각형의 색상을 변경하고, 마우스 오른쪽 버튼을 누르면 작은 정사각형의 색상을 변경하도록 구현해 보자.
[SelectColors.js]
import React from "react";
import { ColorConsumer } from "../contexts/color";
const colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
const SelectColors = () => {
return (
<div>
<h2>색상을 선택하세요</h2>
<ColorConsumer>
{({ actions }) => (
<div style={{ display: "flex" }}>
{colors.map((color) => (
<div
key={color}
style={{
backgroundColor: color,
width: "24px",
height: "24px",
cursor: "pointer",
}}
onClick={() => actions.setColor(color)}
onContextMenu={(e) => {
e.preventDefault(); // 마우스 오른쪽 버튼 클릭 시 메뉴가 뜨는 것을 무시함
actions.setSubColor(color);
}}
/>
))}
</div>
)}
</ColorConsumer>
<hr />
</div>
);
};
export default SelectColors;
* 마우스 오른쪽 버튼 클릭 이벤트는 onContextMenu를 사용하면 된다. 오른쪽 클릭 시 원래 브라우저 메뉴가 나타나지만, 여기서 e.preventDefault() 를 호출하면 메뉴가 뜨지 않는다.
* 브라우저를 열어서 SelectColors 에 있는 정사각형들을 마우스 왼쪽 및 오른쪽 버튼으로 클릭해 보자. 하단에 있는 정사각형들의 색상이 잘 바뀌면 된다.
'React > React_리액트 심화' 카테고리의 다른 글
(6) 리덕스를 사용하여 리액트 애플리케이션 상태 관리하기 1 (0) | 2023.12.13 |
---|---|
(5) 리덕스 라이브러리 이해하기 2 (0) | 2023.12.13 |
(4) 리덕스 라이브러리 이해하기 1 (0) | 2023.12.13 |
(3) Context API 3 (0) | 2023.12.13 |
(1) Context API 1 (0) | 2023.12.12 |