07/25 화

konut ko·2023년 7월 25일
0

더존비즈온5기

목록 보기
43/46

읽어보기

15. Context API

Context API

  • 전역변수, 함수를 관리하기유용하게 해주는 api
  • 예) 리덕스, 리액트라우터, styled-components등의 라이브러리가 Context API 기반으로 구현되어있다.

새 Context 만들기 : ColorContext

const ColorContext = createContext({ color: 'black' });

새 Context를 만들 때는 createContext함수를 사용한다.
파라미터에는 해당 Context의 기본 상태를 지정한다.

Consumer 사용하기 : ColorBox

  • ColorBox 컴포넌트에서 ColorContext 안에 들어있는 Consumer라는 컴포넌트를 통해 색상을 조회.
    (props로 색상을 받아오는것이아닌게 뽀인뜨)
  • <ColorContext.Consumer 태그로 감싸고 안에 {}블록을 쓰고 그안에 콜백함수로 value를 받아서 value.color로 데이터 접근
import React from 'react';
import ColorContext from './ColorContext';

const ColorBox = () => {
    return (
        <>  {/* context에서 정의된 값을 읽기 위해서는 Consumer tag를 사용하여 content영역에 callback 함수를 추가해서 처리한다 */}
            <ColorContext.Consumer>
                {value => (
                    <>
                    <div style={{width: '64px', height: '64px', background : value.color}} />
                    </>
                )}
            </ColorContext.Consumer>
        </>
    );
};

export default ColorBox;

Provider 사용하기 : App.js

  • Provider를 사용하면 Context의 value를 변경할 수 있다.
  • 처음에 context를 생성할 때
    const ColorContext = createContext({ color: 'black' });
    이렇게 넣어준 기본 값은 Provider를 사용하지 않았을 때만 가능하다.
  • 그렇기 때문에 Provider를 쓸 때는 value값을 Provider에 명시해야함!!
import ColorBox from "./ColorBox";
import ColorContext from "./ColorContext";

function ColorApp() {
  return (
      <>
        {/* ColorContext에 값을 기록하기 위해 Provider를 사용하여 값을 설정한다  */}
        <ColorContext.Provider value={{color:'red'}}>
          <ColorBox />
        </ColorContext.Provider>
      </>
  );
  
}

export default ColorApp;

요약
Consumer는 value를 꺼내 쓰는거!
Provider는 value를 변경할 수 있는 거!

실습) reducer 적용하기

context-tutorial 프로젝트의 state폴더

  1. "state"와 "dispatch의 action"이
    => reducer의 인수로 들어간다.
  2. reducer의 switch 문 안에서 action.type으로 구분된다. >>

AppState.js

import ColorComponent from "./ColorComponent";
import { useReducer, useState } from "react";

function reducer(state, action) {

  switch (action.type) {
    case "SETCOLOR": >> color로 바꾸기 전
      return { ...state, color: action.value }; // ...기존상태, 바꿀상태actionkey: 바꿀 상태action값
    case "SETSUBJECT": >> subject로 바꾸기 전
      return { ...state, subject: action.value };
    default:
      return state;
  }

}

function AppState() {
  const [state, dispatch] = useReducer(reducer, {
    color: "black",
    subject: "red",
  });

  const setColor = (color) => {
    dispatch({ type: "color", value: color });
    //dispatch("action임")
  };

  const setSubject = (subject) => {
    dispatch({ type: "subject", value: subject });
  };

  // props 여러개 보내주기 싫으니까 actions라는 변수에 함수 다 담아서 뭉탱이로 보냄.
  const actions = { setColor, setSubject };

  //위코드를 아래와 같이 수정하는 것이 좋다
  // const actions = {
  //   setColor : color => {
  //     setState({...state, color});
  //   },
  //   setSubject : subject => {
  //     setState({...state, subject});
  //   }
  // };

  return (
    <div>
      Here!
      <ColorComponent state={state} actions={actions} />
    </div>
  );
}

export default AppState;

AppState.js의 개선된 코드


위 코드에서 undefined 오류를 방지하는 방법

Provider

실습) contextType 적용하기

함수형 컴포넌트

  • 선언 : const { state } = useContext(ColorContext);
  • 접근 : .. background: state.color }}

클래스형 컴포넌트

  • 선언 : static contextType = ColorContext;
  • 접근 : .. background: this.context.state.color, }}
  • 단점 : 클래스형 컴포넌트에서는 contextType을 하나밖에 사용 못함.

context-tutorial 프로젝트의 context7폴더

ColorBox.js 코드

import React, { Component, useContext } from "react";
import ColorContext, { ColorConsumer } from "./ColorContext";

/*
ColorContext에서 제공하는 속성정보를 useContext() hook함수를 사용하여 처리 하는 방법
이전 ColorConsumer 컨포넌트를 사용하지 않아도 됨 
*/

class ColorBox extends Component {
  static contextType = ColorContext;
  // ColorContext.js 에 있는 Colorcontext에 바로 접근 가능해진다.
  // 위 contextType변수는 아래 render의 return에서 this.context로 받는다.
  // this.context 에 state 에 color ...에 접근하려면
  //                            >> background: this.context.state.color,이렇게 써준다.

  render() {
    return (
      <>
        <div
          style={{
            width: "64px",
            height: "64px",
            background: this.context.state.color,
          }}
        />
        <div
          style={{
            width: "32px",
            height: "32px",
            background: this.context.state.subject,
          }}
        />
      </>
    );
  }
}

// 함수형 컴포넌트에서는 useContext를 쓴다. 
// const ColorBox = () => {
//   const { state } = useContext(ColorContext);

//   return (
//     <>
//       <div style={{ width: "64px", height: "64px", background: state.color }} />
//       <div
//         style={{ width: "32px", height: "32px", background: state.subject }}
//       />
//     </>
//   );
// };

export default ColorBox;

ColorContext.js 코드

const { createContext, useState } = require("react");

const ColorContext = createContext({
  state: { color: "black", subject: "red" },
  actions: {
    setColor: () => {},
    setSubject: () => {},
  },
});

const ColorProvider = ({ children }) => {
  const [color, setColor] = useState("black");
  const [subject, setSubject] = useState("red");

  const value = {
    state: { color, subject }, //상태 변수
    actions: { setColor, setSubject }, //상태 변수 값을 변경 하는 함수
  };
  return (
    <ColorContext.Provider value={value}>{children}</ColorContext.Provider>
  );
};

const { Consumer: ColorConsumer } = ColorContext;

export { ColorProvider, ColorConsumer };

export default ColorContext;

과제) To Do List

모범답안) 예진아씨

profile
보초딩코라 틀린 내용 있을 수도 있습니다. 댓글 지적 환영

0개의 댓글