티스토리 뷰
★ ContextAPI 잘 알아두기 ★
데이터를 전역으로 관리하자 ContextAPI or Redux
API문서
https://ko.reactjs.org/docs/context.html
React를 하다보면 여러 컴포넌트를 거쳐서 자료를 전달해야 하거나, 동시에 같은 자료를 사용해야 하는 경우가 생깁니다.
- Context는 리액트 컴포넌트 간에 어떠한 값을 공유 할 수 있게 해주는 기능입니다.
- 주로 Context는 전역적(global)으로 필요한 값을 다룰 때 사용합니다.
Props로만 데이터를 전달하는 것은 한계가 있다.
리액트 에서는 일반적으로 컴포넌트에게 데이터를 전달해 주어야 할 때 Props를 통해 전달합니다.
그런데, 이 컴포넌트의 형태가 복잡하다면 어떻게 될까요?
G에서 변경된 값을 J로 가져가려면 Root를 거쳐 J로 돌아가야 합니다.
G값을 핸들링하는 함수 또한 Root에서 선언 해야합니다.
Props를 통해 핸들링 함수를 자식 컴포넌트(JS는 변수로 함수를 전달가능) 로 전달해줘야 합니다.
이런 문제는
Context API 또는 Redux를 사용하여 공통(전역)으로 사용하는 데이터를 외부에서 편리하게 사용할 수 있습니다.
ConextAPI 사용방법
createContext() 훅
- ContextAPI를 생성합니다.
- createContext(초기값) 은 객체를 반환합니다.
const 사용할이름 = createContext(초기값)
provider와 consumer
Provider Component | 부모에서 사용 | Context의 변화를 하위 컴포넌트에 알린다. |
Consumer Component | 자식에서 사용 | 부모 Component중 가장 가까운 Provider가 전달하는 데이터를 받아서 사용한다. |
구현순서
- ContextAPI를 생성한다.
- 자식 컴포넌트에서는 Consumer를 이용해서 데이터 받기
- 부모 컴포넌트에서는 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객체)
구현순서
- ContextAPI2.js 생성 (Provider재정의, Consumer를 외부로 export)
- App.js에서 Provider감싸기
- A.js 훅 으로 컨텍스트 사용하기
ContextAPI2.js 에서는...
import { createContext, useState } from "react";
//1. 초기값 설정
const UserContext = createContext(
// { //이거는 확인하기 위한 모형일 뿐임.
// state : {id: 'aaa', name : 'bbb'},
// action : {
// setUser: () => {}
// }
// }
)
//2. Provider 컴포넌트 정의 - 구조분해 할당은 반드시 children으로.
const UserProvider = ({children}) => {
const [user, setUser] = useState({id :'aaa', name : 'bbb'});
const value = {
state : user,
action: {setUser} /* ,js6문법 중 빠른할당구문. 함수를 담아주면 키값이 함수 이름이 되게해주는게 있음 그래서 이렇게 사용. */
}
// console.log(children); //Provider 사이에 있는 컴포넌트.
// console.log(value);
return (
<UserContext.Provider value={value}>{children}</UserContext.Provider>
)
}
//3. 컨슈머, 프로바이더 반환
const UserConsumer = UserContext.Consumer;
export {UserProvider, UserConsumer}
//4. 기본 export
export default UserContext;
* UserProvider 함수에서 리턴부분에
UserContext.Provider 컴포넌트의 사이에는 ContextAPI의 값을 사용할 자식컴포넌트들이 들어옵니다.
return (
<UserContext.Provider value={value}>{children}</UserContext.Provider>
)
App.js에서는...
import A from "./conponent3/A";
import B from "./conponent3/B";
import { UserProvider } from "./contexts/ContextAPI2";
const App = () => {
/*
1. 외부 ContextAPI2의 컨슈머, 프로바이더 export
2. root에서는 export된 프로바이더로 감싸줍니다.
3. 자식컴포넌트에서는 useContext(컨텍스트명)를 이용해서 데이터를 핸들링
*/
return (
<UserProvider>
<A/>
<B/>
</UserProvider>
)
}
export default App;
A.js
import { useContext, useRef } from "react";
import UserContext, { UserConsumer } from "../contexts/ContextAPI2";
const A = () => {
console.log(UserContext);
//초기값을 구조분해 할당
const {state, action} = useContext(UserContext)
//useRef
const input1 = useRef(null);
const input2 = useRef(null);
const handleClick = () => {
// console.log(input1.current.value); //사용자의 입력값
// console.log(input2.current.value);
action.setUser({id: input1.current.value,
name: input2.current.value})
}
return (
/* 2nd - useContext훅을 이용해서 처리*/
<div>
<h3>A컴포넌트</h3>
컨텍스트안에 값: {state.id}<br/>
컨텍스트안에 값: {state.name}<br/>
<div>
<input type="text" ref={input1}/>
<input type="text" ref={input2}/>
<button onClick={handleClick}>컨텍스트데이터변경</button>
</div>
</div>
/* 1st
<UserConsumer>
{
(value) => (
<div>
<h3>A컴포넌트</h3>
컨텍스트안에 값: {value.state.id}<br/>
컨텍스트안에 값: {value.state.name}<br/>
</div>
)
}
</UserConsumer>
*/
)
}
export default A;
B.js
import { useContext } from "react";
import UserContext from "../contexts/ContextAPI2";
import C from "./C";
import D from "./D";
const B = () => {
const {state, action} = useContext(UserContext);
return (
<>
<h3>B컴포넌트</h3>
컨텍스트안에 값: {state.id}<br/>
컨텍스트안에 값: {state.name}<br/>
<C/>
<D/>
</>
)
}
export default B;
C.js
import { useContext } from "react";
import UserContext from "../contexts/ContextAPI2";
const C = () => {
const {state, action} = useContext(UserContext);
return (
<>
<h3>C컴포너트</h3>
컨텍스트안에 값:{state.id}<br/>
컨텍스트안에 값:{state.name}<br/>
</>
)
}
export default C;
D.js
import { useContext, useRef } from "react";
import UserContext from "../contexts/ContextAPI2";
const D = () => {
//초기값을 구조분해 할당
const { state, action } = useContext(UserContext)
//useRef
const input1 = useRef(null);
const input2 = useRef(null);
const handleClick = () => {
// console.log(input1.current.value); //사용자의 입력값
// console.log(input2.current.value);
action.setUser({
id: input1.current.value,
name: input2.current.value
})
}
return (
<>
<h3>D컴포넌트</h3>
컨텍스트안에 값: {state.id}<br />
컨텍스트안에 값: {state.name}<br />
<div>
<input type="text" ref={input1} />
<input type="text" ref={input2} />
<button onClick={handleClick}>컨텍스트데이터변경</button>
</div>
</>
)
}
export default D;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
<기억할것>
*태그는 객체. 그래서 태그를 반환하는 return 구문에는 () 로 감싸줘야함.
*아래 태그 내부에서 함수를 {}로 감싸주는 이유.
JSX 문법 중 하나.
변수는 {} 로 감싸준다.
- 아래 함수부분을 바깥에 선언하고 변수에 담아줄 수 있다.
<Fragment>
<ColorContext.Consumer>
{/* 사용할 곳: Consumer - 함수의 return구문에 화면을 처리할 내용을 작성함 */}
{
(value) => (
<div>
ContextAPI의 사용<br/>
값:{value.color}
</div>
)
}
</ColorContext.Consumer>
</Fragment>
-위와 같은 문장
import { Fragment } from "react"
import ColorContext from "../contexts/ContextAPI";
const ColorComponent = () => {
const name = (value) => (
<div>
ContextAPI의 사용<br/>
값:{value.color}
</div>
)
return (
<Fragment>
<ColorContext.Consumer>
{/* 사용할 곳: Consumer - 함수의 return구문에 화면을 처리할 내용을 작성함 */}
{
name
}
</ColorContext.Consumer>
</Fragment>
)
}
export default ColorComponent;
'React.js' 카테고리의 다른 글
23-01-25) firebase에 react배포하기 (0) | 2023.01.25 |
---|---|
23-01-20) 9. Ajax로 외부 데이터 통신하기 (0) | 2023.01.20 |
23-01-19) 8. React라우터 (0) | 2023.01.19 |
23-01-18) 7.React에 css적용하기 (0) | 2023.01.18 |
6. 리액트 기본훅 (0) | 2023.01.17 |
- Total
- Today
- Yesterday
- 조건문
- 데이터베이스 수업
- 강남역 12번 춣구
- 배열 삭제
- 자바수업
- FOR문
- api 활용
- 가비지 콜렉팅
- 다중 반복문
- nasted class
- 내포 클래스
- 국비학원 수업
- 박문석 선생님
- 배열의 정렬
- 강남 중앙정보처리학원
- 박인욱 강사님
- 자바#자바수강기록
- 국비지원 학원 수업 내용
- 자바스크립트 ES6 문법
- 배열과 탐색
- JS ES6 문법
- 오코노라멘
- 국비학원
- interface #자바
- 자바
- output 스트림
- 중앙정보처리학원
- 자바 api
- 알람 시계 문제
- input 스트림
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |