191119 TIL 뉴스스탠드개발 미션

» 1.5막, TIL (Today I Learned), 코드스쿼드, React.js

뉴스스탠드개발 step1

  • 비동기로 데이터를 가져오고, 가져온 데이터로 언론사 정보를 뿌리고, 선택된 언론사 정보를 뿌려주는 데까지 구현

image

  • babel, webpack으로 환경 설정 해봄
    참고글

  • PressContext API라는 것을 만들어서 사용해보려고 했는데, 뭔가… 효율적인지 잘 모르겠음. 넘 복잡.. 특히 context에서 초기 데이터를 가져와서 state를 설정해주는 포인트가 어려웠음 지금처럼 이렇게 덕지덕지 하는 것이 최선인지…!!
  • 그리고 지금 dispatch에서는 데이터를 가져오는 함수랑 이벤트 핸들링 하는 함수랑 섞여있어서 좀 정리가 안되는 느낌. context를 아예 나누는 게 좋을지??
  • 화살표를 눌렀을 때 다음 언론사로 넘어가게 하기 위해 nextId를 context에 설정했는데 아직 어떻게 활용해야할지 고민중…

context API

  
import React, {
  useState,
  useEffect,
  useReducer,
  createContext,
  useContext,
  useRef
} from "react";

const pressReducer = (state, action) => {
  switch (action.type) {
    case "LOADING":
      return {
        ...state,
        loading: true,
      };
    case "SUCCESS":
      return {
        ...state,
        loading: false,
        data: action.data,
      };
    case "ERROR":
      return {
        ...state,
        error: action.error,
      };
    case "CHANGE":
      return {
        ...state,
        showData: state.data[action.index],
      }
    default:
      throw new Error(`unhandled action type : ${action.type}`);
  }
};

const PressStateContext = createContext();
const PressDispatchContext = createContext();
const PressNextIdContext = createContext();

export const PressProvider = ({ children }) => {
  const [state, dispatch] = useReducer(pressReducer, {
    loading: false,
    data: null,
    error: null,
    showData: null,
  });

  const fetchData = () => {
    dispatch({ type: "LOADING" });
    fetch("../newsData.json")
      .then(res => res.json())
      .then(res => {
        dispatch({type: 'SUCCESS', data: res})
      })
      .catch(e => {
        dispatch({type: 'ERROR', data: e})
      })
  };

  useEffect(() => {
    fetchData();
  }, []);

  const nextId = useRef(1);
  const { loading, data: pressData, error, showData} = state;

  if (loading) return <div>로딩중</div>
  if (error) return <div> 에러 </div>
  if (!pressData) return null;

  return (
      <PressStateContext.Provider value={state}>
        <PressDispatchContext.Provider value={dispatch}>
          <PressNextIdContext.Provider value={nextId}>
            {children}
          </PressNextIdContext.Provider>
        </PressDispatchContext.Provider>
      </PressStateContext.Provider>
  );
};

export const usePressState = () => useContext(PressStateContext);
export const usePressDispatch = () => useContext(PressDispatchContext);
export const usePressNextId = () => useContext(PressNextIdContext);