React - 04

React04

useReducer

  • 상태 업데이트 로직을 컴포넌트에서 분리 시킬 수 있는 Hook함수
    useReducer를 사용하는 부분
// useReducer는 여기서 관리한다.
import React, { useReducer } from "react";
import { reducer } from "../reducer";
import AddState from "./addState";

// 초기값, default value가 존재해야한다.
const initialState = [
  { id: 1, name: "김김김" },
  { id: 2, name: "박박박" },
];

const Reducer = () => {
  // reducer의 정의는 index.js에서 따로 관리한다.
  // reducer에는 상태 업데이트 로직을 담아둔다.
  const [number, dispatch] = useReducer(reducer, initialState);
  // 아래처럼 dispatch하여 값을 보내줘야 reducer에서 값을 받을 수 있다.
  // 여기서 넘겨준 만큼 넘어간다.
  const plusButton = (id, name) => {
    dispatch({ any: "안녕", id: id, name: name });
  };
  const minusButton = (id) => {
    dispatch({ any: "또와", id: id });
  };
  //state처럼 사용 할 수 도 있다., 상태 업데이트는 따로 관리되니 참고.
  // 동일하게 props를 넘겨 줄 수 있다.
  return (
    <>
      {number.length > 0 ? (
        <>
          {number.map((v) => (
            <div>
              {v.id} . {v.name}
            </div>
          ))}
          <AddState
            eventHandler={plusButton}
            eventHandler2={minusButton}
            stateId={number[number.length - 1].id}
          ></AddState>
        </>
      ) : (
        <div>0</div>
      )}
    </>
  );
};

export default Reducer;

reducer를 정의, 상태 업데이트 로직 담당

// 여기가 상태 업데이트 로직임.
// reducer함수는 state와 action을 받는다.
export const reducer = function reducer(state, action) {
  // action에는 dispatch로 보낸 값이 그대로 온다.
  console.log(action);
  // state는 변하기 않는 이상 state의 상태 그대로가 전달된다.
  console.log(state);

  switch (action.any) {
    case "안녕":
      return [...state, { id: action.id, name: action.name }];
    case "또와":
      return state.filter((item) => item.id !== action.id);
    default:
      return state;
  }
};

props를 넘겨 받고 일반적인 state관리

import React, { useState } from "react";
// 단지 props를 받고 일반적인 state관리하는 스크립트
const AddState = ({ eventHandler, eventHandler2, stateId }) => {
  const [name, setName] = useState("");
  const onChange = (e) => {
    setName(e.target.value);
  };
  const addHandler = () => {
    eventHandler(stateId + 1, name);
  };
  const minusHandler = () => {
    eventHandler2(stateId);
  };

  return (
    <>
      <input type="text" value={name} onChange={onChange}></input>
      <button onClick={addHandler}>+</button>
      <button onClick={minusHandler}>-</button>
    </>
  );
};
export default AddState;

ContextAPI

  • 전역 상태관리를 위한 도구라는 점은 Redux와 같다.
  • 기본 내장된 기술로써 사용방법은 다음과 같다.
    전역 context의 정의
import React, { useReducer } from "react";
// 변수를 포함하여 state까지 전역으로 관리하는 코드를 만든다.

//context Api를 이용하여 props로 전달하지 않고 state를 전달 한다.
export const Context = React.createContext();

// 초기 state값
const initialState = [
  { id: 1, name: "이강민" },
  { id: 2, name: "김혜화" },
];

// reducer의 정의, 편의상 여기서 작성했다.
const reducer = (state, action) => {
  switch (action.type) {
    case "INSERTSTATE":
      return [...state, { id: action.id, name: action.name }];
    case "REMOVESTATE":
      // i.id와 action.id가 같지 않는 거만 보임
      return state.filter((i) => i.id !== action.id);
    default:
      return state;
  }
};

const ContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  // reducer로 사용하는 값들을 context를 사용하는 자식에 넘겨준다.
  return (
    <Context.Provider value={{ state, dispatch }}>{children}</Context.Provider>
  );
};
export default ContextProvider;

전역 context의 사용

// context를 받아서 reducer를 사용하는 코드
import React, { useContext } from "react";
import { Context } from "../reducer";
import AddState from "./addstate";

const State = () => {
  // context로 전역으로 선언된 reducer를 사용하려면 다음과 같이 작성한다.
  const { state, dispatch } = useContext(Context);
  // state값과
  console.log(state);

  const onRemove = (e) => {
    dispatch({ type: "REMOVESTATE", id: parseInt(e.target.value) });
  };
  return (
    <>
      {state.map((v) => (
        <>
          <div>
            {v.id}. {v.name}
            <button value={v.id} onClick={onRemove}>
              삭제
            </button>
          </div>
        </>
      ))}
      <AddState></AddState>
    </>
  );
};

export default State;

전역 context의 사용2

// 이 addstate의 상위 컴포넌트는 context이다. 전역으로 선언된 Context를 가져와 reducer를 사용해보자
import React, { useContext, useState } from "react";
import { Context } from "../reducer";

const AddState = () => {
  // 전역 context객체를 가져오자
  const { state, dispatch } = useContext(Context);
  const [name, setName] = useState("");

  const addHandler = () => {
    dispatch({
      type: "INSERTSTATE",
      id: state[state.length - 1].id + 1,
      name: name,
    });
  };
  const onChangeHandler = (e) => {
    setName(e.target.value);
  };

  const reset = () => {
    setName("");
  };
  return (
    <>
      <input
        type="text"
        placeholder="이름을 입력하세요"
        onChange={onChangeHandler}
        value={name}
      ></input>
      <button onClick={addHandler}>추가</button>
      <button onClick={reset}>리셋</button>
    </>
  );
};

export default AddState;

좋은 웹페이지 즐겨찾기