useReducer / useContext

Danbi Cho·2020년 6월 2일
1

타입스크립트로 리액트 Hooks 사용하기

  • 타입스크립트를 사용하는 리액트 컴포넌트에서 useState / useReducer를 사용하여 컴포넌트 상태를 관리할 수 있다.

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);
  • useState의 대체 함수라고 생각할 수 있다. 여러 개인 state를 묶어 사용한다.

  • (state, action) => newState의 형태로 reducer를 받고 dispatch 메서드와 짝의 형태로 현재 state를 반환한다.

  • 많은 하위의 값을 포함하는 복잡한 정적 로직을 만들거나 다음 state가 이전 state에 의존적인 경우에 보통 useState보다 useReducer를 선호한다.

  • 어떤 action인지에 따라 어떤 state를 선택할 것인지 선택한다. action도 type과 name을 가질 수 있다.

initialState : useState에서 처음에 초기 값을 설정해 줬던 것 처럼 여러 개의 State를 처음 초기와 하는 작업.

1. loginView 복사 파일을 만들고 그 파일에 useReducer를 만든다.

import React, { useReducer, useCallback } from "react";

2. 분리되어 있는 reducer 폴더에 reducer 파일을 만든다.
switch - case문을 이용하여 action type과 case를 설정 해준다.
loginView에 import 해서 사용한다.

 const reducer = (state, action) => {
 switch (action.type) {
   case "PROCEED_STAGE":
     return {
       ...state,
       stageIdx: ++action.stageIdx,
     };
   case "NAME_CHECK":
     return {
       ...state,
       userInput: {
         ...state.userInput,
         name: action.value,
       },
     };
   case "ADD_USER_INFO":
     return {
       ...state,
       userInput: {
         ...state.userInput,
         [action.inputName]: action.value,
       },
     };
   case "ADD_ERROR_MSG":
     return {
       ...state,
       errorMsg: action.message,
     };
   default:
     return state;
 }
};
export default reducer;

3. loginView 이벤트 핸들러에서 dispatch를 사용하여 type을 확인 하고 값을 변경 한다.

const loginHandler = useCallback((e) => {
    if (userName !== user[0].id) {
      dispatch({
        type: "ADD_ID_ERROR_MSG",
        message: "아이디가 일치하지 않습니다.",
      });
    }

    if (userPw !== user[0].password) {
      dispatch({
        type: "ADD_PW_ERROR_MSG",
        message: "비밀번호가 일치하지 않습니다.",
      });
    }

    if (userName === user[0].id && userPw === user[0].password) {
      props.history.push(`/`);
    } else {
      console.log("아이디와 비밀번호를 확인해주세요");
    }
  }, []);

React Context

Props Drilling

  • 컴포넌트를 작성하고 사용하다 보면 해당 컴포넌트에는 필요가 없지만 하위 컴포넌트에 전달하기 위해 Props를 받아야 할 때가 있다.
  • 이러한 패턴을 Props Drilling이라고 한다.
  • Props Drilling을 사용하여 컴포넌트를 작성하면 컴포넌트 간 의존하는 형태로 발전하고, 재활용이 불가능하지만 분리만 해 놓은 컴포넌트를 작성하게 되는 좋지 않은 패턴이다.

useContext

  • React에서 상태 관리를 하기 위해 사용한다. useContext를 전역변수 처럼 사용할 수 있다.
const value = useContext(MyContext);
  • context 객체를 받아 그 context의 현재 값을 반환한다.

  • context의 현재 값은 트리 안에서 이 Hook을 호출하는 컴포넌트에 가장 가까이 있는 <MyContext.Provider>의 value prop에 의해 결정 된다.

  • 컴포넌트에서 가장 가까운 <MyContext.Provider>가 갱신되면 그 MyContext provider에게 전달된 가장 최신의 context value를 사용하여 렌더러를 트리거 한다.

useContext를 Context.Provider와 같이 사용한다.

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}
profile
룰루랄라! 개발자 되고 싶어요🙈

0개의 댓글