5 분 안에 React Context 배우기-초보자 튜토리얼
본문
React의 Context API는 종종 Redux를 대체하는 많은 사람들에게 선택된 상태 관리 도구가 되었습니다.
이 빠른 5 분 자습서에서는 컨텍스트란 무엇이고 어떻게 사용하는지 소개합니다.
https://www.freecodecamp.org/news/react-context-in-5-minutes/
이 주제에 대한 적절한 소개를 원하는 경우, 곧 진행될 고급 React 코스의 대기자 명단에 참여하거나 초보자 일 경우 React에 대한 무료 소개 코스를 확인하십시오.
아래 상자가 별도의 구성 요소를 나타내는 이 트리를 고려하십시오.
맨 아래 컴포넌트에 상태를 쉽게 추가 할 수 있지만 지금까지 컴포넌트의 형제로 데이터를 전달하는 유일한 방법은 상태를 상위 컴포넌트로 이동 한 다음 소품을 통해 형제로 다시 전달하는 것입니다.
나중에 상태를 가진 구성 요소의 형제에 데이터가 필요하다는 것을 알게 되면 상태를 다시 들어 올려서 아래로 전달해야 합니다.
이 솔루션이 작동하는 동안 다른 지점의 구성 요소에 데이터가 필요한 경우 문제가 시작됩니다.
이 경우 중간 수준에 필요하지 않더라도 모든 중간 구성 요소를 통해 응용 프로그램의 최상위 수준에서 아래쪽에 데이터가 필요한 구성 요소로 상태를 전달해야 합니다. 이 지루하고 시간 소모적인 프로세스를 prop drilling이라고 합니다.
Context API가 제공되는 곳입니다. 모든 수준에서 소품을 전달하지 않고도 공급자-소비자 쌍을 통해 구성 요소 트리를 통해 데이터를 전달하는 방법을 제공합니다. 데이터와 함께 캐치 (Catch)를 수행하는 컴포넌트로 생각하십시오. 중개 컴포넌트는 어떤 일이 일어나고 있는지 "알지"못할 수도 있습니다.
이를 설명하기 위해 이 펑키 한 (매우 유용한) 매일 밤 전환 이미지를 만듭니다.
전체 코드를 보려면 Scrimba 놀이터에서 이 기사를 확인하십시오.
컨텍스트 만들기
시작하기 위해 새로운 컨텍스트를 만듭니다. 전체 앱이 이에 액세스 할 수 있도록 index.js로 이동하여 ThemeContext.Provider에서 앱을 래핑합니다.
또한 가치 제안을 제공자에게 전달합니다. 이것은 우리가 저장하고자 하는 데이터를 보유합니다. 지금은 'Day'로 하드 코딩했습니다.
import React from "react";
import ReactDOM from "react-dom";
import ThemeContext from "./themeContext";
import App from "./App";
ReactDOM.render(
<ThemeContext.Provider value={"Day"}>
<App />
</ThemeContext.Provider>,
document.getElementById("root")
);
contextType으로 컨텍스트 소비
현재 App.js에서는 <Image /> 구성 요소를 반환합니다.
import React from "react";
import Image from "./Image";
class App extends React.Component {
render() {
return (
<div className="app">
<Image />
</div>
);
}
}
export default App;
우리의 목표는 Context를 사용하여 렌더링 하려는 이미지에 따라 Image.js의 className을 Day에서 Night로 전환하는 것입니다. 이를 위해 ContextType이라는 컴포넌트에 정적 속성을 추가 한 다음 문자열 보간을 사용하여 <Image /> 컴포넌트의 classNames에 추가합니다.
이제 classNames는 prop 값의 문자열을 포함합니다. 참고 : 버그를 방지하기 위해 ThemeContext를 자체 파일로 옮겼습니다.
import React from "react";
import Button from "./Button";
import ThemeContext from "./themeContext";
class Image extends React.Component {
render() {
const theme = this.context;
return (
<div className={`${theme}-image image`}>
<div className={`${theme}-ball ball`} />
<Button />
</div>
);
}
}
Image.contextType = ThemeContext;
export default Image;
Context.Consumer
불행히도 이 방법은 클래스 기반 구성 요소에서만 작동합니다. Hooks in React에 대해 이미 배운 적이 있다면 요즘 기능적 구성 요소로 무엇이든 할 수 있다는 것을 알게 될 것입니다. 따라서 올바른 측정을 위해서는 구성 요소를 기능 구성 요소로 변환 한 다음 ThemeContext.Consumer 구성 요소를 사용하여 앱을 통해 정보를 전달해야 합니다.
이것은 <ThemeContext.Consumer>의 인스턴스와 요소 (자식이있는 곳) 내에서 요소를 감싸서 요소를 반환하는 함수를 제공함으로써 수행됩니다. 이것은 "렌더 소품"패턴을 사용하여 렌더링 할 JSX를 반환하는 자식으로 일반 함수를 제공합니다.
import React from "react";
import Button from "./Button";
import ThemeContext from "./themeContext";
function Image(props) {
// We don't need this anymore
// const theme = this.context
return (
<ThemeContext.Consumer>
{theme => (
<div className={`${theme}-image image`}>
<div className={`${theme}-ball ball`} />
<Button />
</div>
)}
</ThemeContext.Consumer>
);
}
// We don't need this anymore
// Image.contextType = ThemeContext;
export default Image;
참고 : <ThemeContext.Consumer>에서 <Button /> 구성 요소도 래핑해야 합니다. 나중에 버튼에 기능을 추가 할 수 있습니다.
import React from "react";
import ThemeContext from "./themeContext";
function Button(props) {
return (
<ThemeContext.Consumer>
{context => (
<button className="button">
Switch
<span role="img" aria-label="sun">
?
</span>
<span role="img" aria-label="moon">
?
</span>
</button>
)}
</ThemeContext.Consumer>
);
}
export default Button;
컨텍스트 제공자 추출
현재 제공 업체를 통해 하드 코딩 된 값을 전달하고 있지만 버튼을 사용하여 밤낮으로 전환하는 것이 목표입니다.
이를 위해서는 Provider를 별도의 파일로 옮기고 이 경우 ThemeContextProvider라는 자체 구성 요소에 넣어야 합니다.
import React, { Component } from "react";
const { Provider, Consumer } = React.createContext();
class ThemeContextProvider extends Component {
render() {
return <Provider value={"Day"}>{this.props.children}</Provider>;
}
}
export { ThemeContextProvider, Consumer as ThemeContextConsumer };
참고 : value 속성은 이제 새 파일 ThemeContext.js에서 처리되므로 index.js에서 제거해야 합니다.
Changing Context
버튼을 연결하려면 먼저 ThemeContextProvider에 상태를 추가하십시오.
import React, { Component } from "react";
const { Provider, Consumer } = React.createContext();
// Note: You could also use hooks to provide state and convert this into a functional component.
class ThemeContextProvider extends Component {
state = {
theme: "Day"
};
render() {
return <Provider value={"Day"}>{this.props.children}</Provider>;
}
}
export { ThemeContextProvider, Consumer as ThemeContextConsumer };
다음으로 낮과 밤을 전환하는 방법을 추가합니다.
toggleTheme = () => {
this.setState(prevState => {
return {
theme: prevState.theme === "Day" ? "Night" : "Day"
};
});
};
이제 value 속성을 this.state.theme로 변경하여 state에서 정보를 반환합니다.
render() {
return <Provider value={this.state.theme}>{this.props.children}</Provider>;
}
}
다음으로 {theme : this.state.theme, toggleTheme : this.toggleTheme}를 포함하는 객체로 값을 변경하고 단일 값을 사용하여 객체에서 테마를 찾는 모든 위치를 업데이트합니다. 이는 모든 주제가 맥락이 되고 가치에 대한 주제가 맥락이 주제가 됨을 의미합니다.
마지막으로 버튼에 onClick 이벤트를 수신하고 context.toggleTheme을 실행하도록 지시합니다. 그러면 제공자의 상태를 사용하는 소비자가 업데이트 됩니다. 버튼 코드는 다음과 같습니다.
import React from "react";
import { ThemeContextConsumer } from "./themeContext";
function Button(props) {
return (
<ThemeContextConsumer>
{context => (
<button onClick={context.toggleTheme} className="button">
Switch
<span role="img" aria-label="sun">
?
</span>
<span role="img" aria-label="moon">
?
</span>
</button>
)}
</ThemeContextConsumer>
);
}
export default Button;
우리의 버튼은 이제 한 번의 클릭으로 밤낮으로 이미지를 전환합니다!
Context caveats
코드의 모든 좋은 것들과 마찬가지로 Context를 사용하는 데 주의 해야 할 점이 있습니다.
- props을 한두 층 아래로 뚫는 것을 피하기 위해 문맥을 사용하지 마십시오. 컨텍스트는 애플리케이션의 많은 부분에 필요한 상태를 관리하는 데 좋습니다. 그러나 정보를 몇 개의 레이어로 전달하면 props 드릴링이 더 빠릅니다.
- 컨텍스트를 사용하여 로컬로 유지해야 하는 상태를 저장하지 마십시오. 예를 들어, 사용자의 양식 입력을 저장해야 하는 경우 컨텍스트가 아닌 로컬 상태를 사용하십시오.
- 항상 앱의 최상위 구성 요소가 아닌 트리에서 가능한 가장 낮은 공통 부모 주위에 Provider를 래핑하십시오. 과잉 필요가 없습니다.
- 마지막으로, 가치 props으로 객체를 전달하면 성능을 모니터링하고 필요에 따라 리팩터링 하십시오. 성능 저하가 눈에 띄지 않는 한 필요하지 않을 것입니다.
마무리
이 예제는 매우 간단하며 앱에 상태를 넣고 props을 통해 전달하는 것이 더 쉬울 것입니다. 그러나 트리에서 그 위에 있는 구성 요소와 독립적으로 데이터에 액세스 할 수 있는 소비자를 보유하는 힘이 있기를 바랍니다.
- 이전글무료 Bootstrap 4 관리자 테마 19.11.24
- 다음글React, Angular 및 Vue의 통계 분석 19.11.20