인프런 커뮤니티 질문&답변

뽀개즈아님의 프로필 이미지
뽀개즈아

작성한 질문수

[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

12.10) Home 페이지 구현하기 1. UI

작성완료 시 onCreate 함수 호출 못함

작성

·

443

0

App.js에서 onCreate함수를 가지고 오지 못하고 있는데 어디서 오류가 났는지 찾지못하고있어요ㅠㅠ! 도와주세요!

코드보여드릴게여 ㅠㅠ

오류상황

Cannot destructure property 'onCreate' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
TypeError: Cannot destructure property 'onCreate' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
    at DiaryEdit (http://localhost:3000/static/js/bundle.js:344:5)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26416:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:29702:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:30998:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:16008:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:16052:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:16109:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:35983:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:35230:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:35153:9)

App.js

import React, { useReducer, useRef } from "react";
import "./App.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";

const reducer = (state, action) => {
  // return state;
  let newState = [];
  switch (action.type) {
    case "INIT": {
      return action.data;
    }
    case "CREATE": {
      newState = [...action.data, ...state];
      break;
    }
    case "REMOVE": {
      newState = state.filter((it) => it.id !== action.targetId);
      break;
    }
    // 모든 부분을 수정해야해서 다 받아옴
    case "EDIT": {
      newState = state.map((it) =>
        it.id === action.targetId ? { ...action.data } : it
      );
      break;
    }
    default:
      return state;
  }
  return newState;
};

export const DiaryStateContext = React.createContext();
export const DiaryDispatchContext = React.createContext();

const dummyData = [
  {
    id: 1,
    emotion: 1,
    content: "일기 1번",
    date: 1687326683094,
  },
  {
    id: 2,
    emotion: 2,
    content: "일기 2번",
    date: 1687326683096,
  },
  {
    id: 3,
    emotion: 3,
    content: "일기 3번",
    date: 1687326683097,
  },
  {
    id: 4,
    emotion: 4,
    content: "일기 4번",
    date: 1687326683098,
  },
  {
    id: 5,
    emotion: 5,
    content: "일기 5번",
    date: 1687326683099,
  },
  {
    id: 6,
    emotion: 3,
    content: "일기 6번",
    date: 1787321680269,
  },
];

function App() {
  const [data, dispatch] = useReducer(reducer, dummyData);
  // console.log(new Date().getTime());

  const dataId = useRef(0);

  const onCreate = (date, content, emotion) => {
    dispatch({
      type: "CREATE",
      data: {
        id: dataId.current,
        date: new Date(date).getTime(),
        content,
        emotion,
      },
    });
    dataId.current += 1;
  };

  const onRemove = (targetId) => {
    dispatch({ type: "REMOVE", targetId });
  };

  const onEdit = (targetId, date, content, emotion) => {
    dispatch({
      type: "EDIT",
      data: {
        id: targetId,
        date: new Date(date).getTime(),
        content,
        emotion,
      },
    });
  };
  return (
    <DiaryStateContext.Provider value={data}>
      <DiaryDispatchContext.Provider value={{ onCreate, onEdit, onRemove }}>
        <BrowserRouter>
          <div className="App">
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="/new" element={<New />} />
              <Route path="/edit" element={<Edit />} />
              <Route path="/diary/:id" element={<Diary />} />
              {/* <Route path="/diary" element={<Diary />} /> */}
            </Routes>
          </div>
        </BrowserRouter>
      </DiaryDispatchContext.Provider>
    </DiaryStateContext.Provider>
  );
}

export default App;

DiaryEdit.js

import { useNavigate } from "react-router-dom";
import React, { useState, useRef, useContext } from "react";

import MyHeader from "./MyHeader";
import MyButton from "./MyButton";
import EmotionItem from "./EmotionItem";
import DiaryDispatchContext from "./../App";

// 감정에 대한 데이터
const emotionList = [
  {
    emotion_id: 1,
    emotion_img: process.env.PUBLIC_URL + `assets/emotion1.png`,
    emotion_descript: "완전 좋음",
  },
  {
    emotion_id: 2,
    emotion_img: process.env.PUBLIC_URL + `assets/emotion2.png`,
    emotion_descript: "좋음",
  },
  {
    emotion_id: 3,
    emotion_img: process.env.PUBLIC_URL + `assets/emotion3.png`,
    emotion_descript: "보통",
  },
  {
    emotion_id: 4,
    emotion_img: process.env.PUBLIC_URL + `assets/emotion4.png`,
    emotion_descript: "나쁨",
  },
  {
    emotion_id: 5,
    emotion_img: process.env.PUBLIC_URL + `assets/emotion5.png`,
    emotion_descript: "완전 나쁨",
  },
];

// 달력에 오늘의 날짜를 기본 날짜로 구현하기
export const getStringDate = (date) => {
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  let day = date.getDate();

  if (month < 10) {
    month = `0${month}`;
  }

  if (day < 10) {
    day = `0${day}`;
  }

  return `${year}-${month}-${day}`;
};

const DiaryEdit = () => {
  const contentRef = useRef();
  const navigator = useNavigate();
  const [date, setDate] = useState(getStringDate(new Date()));

  // 어떤 감정을 선택했는지 state에 저장
  const [emotion, setEmotion] = useState(3);
  const [content, setContent] = useState("");
  const { onCreate } = useContext(DiaryDispatchContext);

  const handleClickEmotion = (emotion) => {
    setEmotion(emotion);
  };

  const handleSubmit = () => {
    if (content.length < 1) {
      contentRef.current.focus();
      return;
    }
    onCreate(date, content, emotion);
  };

  return (
    <div className="DiaryEdit">
      <MyHeader
        headText={"새로운 일기 쓰기"}
        leftChild={
          <MyButton text={"< 뒤로가기"} onClick={() => navigator(-1)} />
        }
      />
      <div>
        <section>
          <h4>오늘은 언제인가요?</h4>
          <div className="input_box">
            <input
              className="input_date"
              value={date}
              onChange={(e) => setDate(e.target.value)}
              type="date"
            />
          </div>
        </section>
        <section>
          <h4>오늘의 감정</h4>
          <div className="input_box emotion_list_wrapper">
            {emotionList.map((it) => (
              <EmotionItem
                key={it.emotion_id}
                {...it}
                onClick={handleClickEmotion}
                isSelected={it.emotion_id === emotion}
              />
            ))}
          </div>
        </section>
        <section>
          <h4>오늘의 일기</h4>
          <div className="input_box text_wrapper">
            <textarea
              placeholder="오늘은 어땠나요?"
              ref={contentRef}
              vlaue={content}
              onChange={(e) => setContent(e.target.value)}
            />
          </div>
        </section>
        <section>
          <div className="control-box">
            <MyButton text={"취소하기"} onClick={() => navigator(-1)} />
            <MyButton
              text={"작성완료"}
              type={"positive"}
              onClick={handleSubmit}
            />
          </div>
        </section>
      </div>
    </div>
  );
};

export default DiaryEdit;

답변 1

0

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

정확한 오류의 원인을 확인해보기 위해서

현재 문제가 발생한 프로젝트를 깃허브나 코드샌드박스에 업로드하신 다음

링크로 공유주시면 직접 확인해보겠습니다!

뽀개즈아님의 프로필 이미지
뽀개즈아
질문자

코드샌드박스에 올리는 과정중에 오류를 찾았습니다. 역시 오타가 났었네요 ㅠㅠ! 빠른답변감사합니다!

뽀개즈아님의 프로필 이미지
뽀개즈아

작성한 질문수

질문하기