2022-06-28
React Context
어떤 component tree 내에서는 최상위 component부터 최말단 component에 걸쳐 전역(globa)으로 관리해야 할 데이터가 필요하다.
이때, React Context는 전역 데이터를 단순하지만 체계적인 방식으로 접근할 수 있도록 도와준다.
import Button from "./components/Button";
import Title from "./components/Title";
import Message from "./components/Message";
import { Fragment, Component } from 'react';
class App extends Component {
state = {lang: "en"};
toggleLang = ()=>{
this.setState(({lang}) => ({
lang: lang ==="en"? "kr" : "en"
}));
};
render(){
const {lang} = this.state;
return(
<Fragment>
<Button lang={lang} toggleLang={this.toggleLang}/>
<Title lang={lang}/>
<Message lang={lang}/>
</Fragment>
);
}
}
export default App;
import React from "react";
function Title({lang}){
const text = lang === "en"? "컨텍스트" : "Context";
return <h1>{text}</h1>;
}
export default Title;
class Message extends Component{
render(){
const {lang} = this.props;
if(lang === "en") //수행해야되는 것이 하나뿐일 땐 소괄호, 여러개일땐 중괄호
return(
<p>
컨텍스트는 모든 레벨에서 일일이 props를 넘기지 않고도 컴포넌트 트리에 걸쳐서 데이터를 전달할 수 있는 방법을 제공합니다.
</p>
);
else
return(
<p>
Context provides a way to pass data through the component tree without having to pass props down manually at ever level.
</p>
);
}
}
기존에는 props로 매개변수를 받았으나, 이제 그것을 context로 받겠다는 것.
import {createContext} from "react";
const LangContext = createContext("en");
export default LangContext;
import Button from "./components/Button";
import Title from "./components/Title";
import Message from "./components/Message";
import { Component } from 'react';
import LangContext from "./LangContext";
class App extends Component {
state = {lang: "en"};
toggleLang = ()=>{
this.setState(({lang}) => ({
lang: lang ==="en"? "kr" : "en"
}));
};
render(){
const {lang} = this.state;
return(
<LangContext.Provider value = {lang}>
<Button toggleLang={this.toggleLang} />
<Title />
<Message />
</LangContext.Provider>
);
}
}
export default App;
import React from "react";
import LangContext from "../LangContext";
function Title(){
return (
<LangContext.Consumer>
{lang => {
const text = lang ==="en"? "Context" : "컨텍스트";
return <h1>{text}</h1>
}}
</LangContext.Consumer>
)
}
export default Title;
import React, { useContext } from "react";
import LangContext from "./LangContext";
function Button({ toggleLang }) {
const lang = useContext(LangContext);
return <button onClick={toggleLang}>{lang}</button>;
}
// const {lang} = this.props; 를 아래로 변경
// const lang = this.context;
import React, { Component } from "react";
import LangContext from "./LangContext";
class Message extends Component {
static contextType = LangContext;
render() {
const lang = this.context;
if (lang === "en")
return (
<p>
"Context provides a way to pass data through the component tree
without having to pass props down manually at every level"
</p>
);
else
return (
<p>
"컨텍스트는 모든 레벨에서 일일이 props를 넘기지 않고도 컴포넌트 트리에
걸쳐서 데이터를 전달할 수 있는 방법을 제공합니다."
</p>
);
}
}
HTML은 많은 트리구조를 쓴다. 근데 그 구조가 간단하면 충분히 props로도 데이터를 주고 받을 수 있다. 하지만 주고 받아야하는 데이터가 많아지면 props로만 주고 받기가 힘들다.
따라서 트리 내에서 최상위, 최말단 컴포넌트들을 전역적으로 쓰이는 데이터를 처리하고 싶을 때 context를 만들어서 쓴다.
import React, {Component} from 'react';
class AddNumber extends Component{
render() {
return(
<div>
<h1>Add Number</h1>
<input type="button" value="+"></input>
<input type="text" value="+"></input>
</div>
);
}
}
class AddNumberRoot extends Component {
render(){
return (
<div>
<h1>Add Number Root</h1>
<AddNumber></AddNumber>
</div>
);
}
}
class DisplayNumber extends Component {
render() {
return(
<div>
<h1>Display Number</h1>
<input type="text" value="0" readOnly></input>
</div>
);
}
}
class DisplayNumberRoot extends Component{
render() {
return (
<div>
<h1>Display Number Root</h1>
<DisplayNumber></DisplayNumber>
</div>
);
}
}
function App() {
return(
<div className="App">
<h1>Root</h1>
</div>
);
}
export default App;
src에 components 폴더를 만들고 아래의 파일들 추가
Addnumber.jsx
, AddnumberRoot.jsx
, DisplayNumber.jsx
, DisplayNumberRoot.jsx
각 함수를 파일명에 맞게 집어넣는다. (이로써 객체가 됨)
AddnumberRoot와 DisplayNumberRoot 파일에는 Addnumber, DisplayNumber를 이용하니, import 해주어야한다.
import Addnumber from "./components/Addnumber";
import DisplayNumber from "./components/DisplayNumber";
import './App.css';
import React, {Component} from 'react';
import AddNumberRoot from './components/AddNumberRoot';
import DisplayNumberRoot from './components/DisplayNumberRoot';
function App() {
return (
<div className="App">
<h1>Root</h1>
<AddNumberRoot></AddNumberRoot>
<DisplayNumberRoot></DisplayNumberRoot>
</div>
);
}
export default App;
import React, { Component } from "react";
class AddNumber extends Component {
render() {
return (
<div>
<h1>Add Number</h1>
<input type="button" value="+"></input>
<input type="text" value="0"></input>
</div>
);
}
}
export default AddNumber;
import React, { Component } from "react";
import AddNumber from "../components/AddNumber";
class AddNumberRoot extends Component {
render() {
return (
<div>
<h1>Add Number Root</h1>
<AddNumber></AddNumber>
</div>
);
}
}
export default AddNumberRoot;
import React, { Component } from "react";
import DisplayNumber from "../components/DisplayNumber";
class DisplayNumberRoot extends Component {
render() {
return (
<div>
<h1>Display Number Root</h1>
<DisplayNumber></DisplayNumber>
</div>
);
}
}
export default DisplayNumberRoot;
import React, { Component } from "react";
class DisplayNumber extends Component {
render() {
return (
<div>
<h1>Display Number</h1>
<input type="text" value="0" readOnly></input>
</div>
);
}
}
export default DisplayNumber;
div {
border : 5px solid #764abc;
margin : 10px;
color : #764abc;
padding: 10px;
}
아직 문법을 잘 모르겠다
함수형 컴포넌트 이름은 항상 대문자로 시작한다
기본 형태
function App(){
return(
<div>{변수명}</div>
);
}
컴포넌트로 분리를 했을 때 파일 수는 많아지지만 찾아서 수정할 때는 용이해보인다. context를 썼을 때 어떤 점이 더 용이한 건지 찾아봐야할 듯