[개발일지 39일차] React Context

MSJ·2022년 6월 28일
0

WEB

목록 보기
39/41
post-thumbnail

2022-06-28

React Context

어떤 component tree 내에서는 최상위 component부터 최말단 component에 걸쳐 전역(globa)으로 관리해야 할 데이터가 필요하다.

이때, React Context는 전역 데이터를 단순하지만 체계적인 방식으로 접근할 수 있도록 도와준다.

실습 1) 변역 버튼 : 기존 구현방식

App.js

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;

Title.jsx

import React from "react";

function Title({lang}){
    const text = lang === "en"? "컨텍스트" : "Context";
    return <h1>{text}</h1>;
}

export default Title;

Message.jsx

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>
            );
    }
    
}

Context 접근 방법

  1. consumer로 접근
  2. useContext 접근
  3. contextType 접근

실습 2) 번역 버튼 : 컨텍스트 써보기

기존에는 props로 매개변수를 받았으나, 이제 그것을 context로 받겠다는 것.

1. 먼저 LangContext.js를 src폴더에 바로 만들고 작성.

import {createContext} from "react";

const LangContext = createContext("en");

export default LangContext;

2. App.js와 다른 파일들에 LangContext.js 를 import.

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;

3. Title.js (Consumer로 접근)

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;

4. Button.js (usdContext로 Context접근)

import React, { useContext } from "react";
import LangContext from "./LangContext";

function Button({ toggleLang }) {
  const lang = useContext(LangContext);
  return <button onClick={toggleLang}>{lang}</button>;
}

5. Message.js

 // 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>
      );
  }
}

왜 context를 쓰나?

HTML은 많은 트리구조를 쓴다. 근데 그 구조가 간단하면 충분히 props로도 데이터를 주고 받을 수 있다. 하지만 주고 받아야하는 데이터가 많아지면 props로만 주고 받기가 힘들다.

따라서 트리 내에서 최상위, 최말단 컴포넌트들을 전역적으로 쓰이는 데이터를 처리하고 싶을 때 context를 만들어서 쓴다.

실습 3) 숫자 박스 : 기존 구현방식

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;

실습 4) 숫자 박스 : 컴포넌트 식

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";

1. App.js

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;

2. Addnumber.jsx

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;

3. AddnumberRoot.jsx

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;

4. DisplayNumber.jsx

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;

5. DisplayNumberRoot.jsx

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;
  1. App.css
div {
	border : 5px solid #764abc;
    margin : 10px;
    color : #764abc;
    padding: 10px;
}

어려웠던 점

아직 문법을 잘 모르겠다

해결방법

함수형 컴포넌트 이름은 항상 대문자로 시작한다

기본 형태

function App(){
	return(
		<div>{변수명}</div>
        );
    }

소감

컴포넌트로 분리를 했을 때 파일 수는 많아지지만 찾아서 수정할 때는 용이해보인다. context를 썼을 때 어떤 점이 더 용이한 건지 찾아봐야할 듯

profile
제로부터 시작하는 프로그래밍&코딩

0개의 댓글