해결된 질문
작성
·
554
0
윈터로드님 알려주신 덕분에 완강할수잇었습니다ㅠㅠ 인프런 강의 첫 수강완료증을 받앗네요
제 프로젝트에 큰오류를 발견했습니다,,,, 새일기쓰면 똑같은게 2개가 만들어지는데 이거 어디서 오류를 수정해야 하는지알수잇을까요?
답변 1
0
안녕하세요 이정환입니다.
완강하셨다니 감사합니다 그리고 축하드립니다!
코드를 보지 않고는 오류를 찾기 어렵습니다 🥲
오류가 발생한 코드를 코드샌드박스 또는 깃허브에 업로드 하신 다음 링크로 공유 부탁드립니다.
//App.js
import React, { useReducer, useRef, useEffect } 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)=>{
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.data.id? [...action.data]: it)
break;
}
default:
return state;
}
localStorage.setItem("diary", JSON.stringify(newState))
return newState;
};
export const DiaryStateContext = React.createContext();
export const DiaryDispatchContext = React.createContext();
function App() {
useEffect(() => {
const item1 = localStorage.getItem("item1");
const item2 = localStorage.getItem("item2");
const item3 = JSON.parse(localStorage.getItem("item3"));
console.log(item1, item2, item3)
}, []);
const [data, dispatch] = useReducer(reducer,[]);
useEffect(() =>{
const localData = localStorage.getItem('diary');
if(localData) {
const diaryList = JSON.parse(localData).sort(
(a,b)=> parseInt(b.id) - parseInt(a.id)
);
if(diaryList.length >= 1) {
dataId.current = parseInt(diaryList[0].id) + 1;
dispatch({ type: "INIT", data: diaryList });
}
}
}, []);
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion)=>{
dispatch({
type :"CREATE",
data:{
id: dataId.current,
date: new Date(date).getTime(),
content,
emotion,
},
});
dataId.current += 1;
};
// REMOVE
const onRemove = (targetId) => {
dispatch({type: "REMOVE",targetId});
}
// EDIT
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/:id" element={<Edit />} />
<Route path="/diary/:id" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
);
};
export default App;
//DiaryEditor.js
import { useState, useRef, useContext, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { DiaryDispatchContext } from './../App.js';
import MyHeader from './MyHeader';
import MyButton from './MyButton';
import EmotionItem from './EmotionItem';
import { getStringDate } from '../util/date.js';
import { emotionList } from '../util/emotion.js';
const env = process.env;
env.PUBLIC_URL = env.PUBLIC_URL || "";
const DiaryEditor = ({isEdit,originData}) => {
const contentRef = useRef();
const [content, setContent] = useState("");
const [emotion, setEmotion] = useState(3);
const [date, setDate] = useState(getStringDate(new Date()));
const { onCreate, onEdit, onRemove } = useContext(DiaryDispatchContext)
const handleClickEmote = useCallback((emotion) => {
setEmotion(emotion);
}, []);
const navigate = useNavigate();
const handleSubmit = ()=> {
if(content.length < 1){
contentRef.current.focus();
return;
}
if(window.confirm(isEdit ? "일기를 수정하시겠습니까?" : "새로운 일기를 작성하시겠습니까?")){
if(!isEdit){
onCreate(date, content, emotion);
} else{
onEdit(originData.id, date, content, emotion);
}
}
onCreate(date,content,emotion);
navigate('/', { replace: true });
};
const handleRemove = () => {
if(window.confirm('정말 삭제하시겠습니까?')){
onRemove(originData.id);
navigate('/',{replace:true})
}
}
useEffect(()=>{
if(isEdit) {
setDate(getStringDate(new Date(parseInt(originData.date))));
setEmotion(originData.emotion);
setContent(originData.content);
}
}, [isEdit,originData]);
return (
<div className='DiaryEditor'>
<MyHeader
headText={isEdit ? "일기 쓰기" : "새 일기쓰기"}
leftChild={
<MyButton text={"< 뒤로가기"} onClick={() => navigate(-1)} />
}
rightChild={isEdit && <MyButton text={"삭제하기"} type={"negative"} onClick={handleRemove}/>
}
/>
<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={handleClickEmote}
isSelected={it.emotion_id === emotion}
/>
))}
</div>
</section>
<section>
<h4>오늘의 일기</h4>
<div className='input_box text_wrapper'>
<textarea
placeholder="오늘은 어땟나요"
ref={contentRef} value={content}
onChange={(e) => setContent(e.target.value)}/>
</div>
</section>
<section>
<div className='control_box'>
<MyButton text={'취소하기'} onClick={()=> navigate(-1)} />
<MyButton text={'작성완료'} type={"positive"} onClick={handleSubmit} />
</div>
</section>
</div>
</div>
);
}
export default DiaryEditor;
hwji님 안녕하세요 이정환입니다.
아무래도 모든 파일의 내용을 확인해야 정확한 오류를 찾을 수 있기 때문에 지금 올려주신 코드만으로는 정확한 파악이 어렵습니다
오류의 원인이 올려주신 두 파일(App, Editor)에 존재할 수도 있겠지만 혹여나 아닐 수도 있거든요
코드샌드박스 활용법이 어렵다면 제 메일로 전체 프로젝트 폴더(node_modules는 제거해주세요)를 압축해 보내주세요 그럼 제가 다운로드하고 환경을 설정한 다음 확인해 어떤 부분에 오류가 있는지 정확히 찾아서 알려드릴 수 있을 것 같습니다.
아래 메일 주소로 보내주시면 확인해보겠습니다.
king199777@gmail.com
제가 깃허브랑 코드샌드박스 사용법을 잘몰라서 소스만 공유하겠습니다ㅠ 깃허브도 공부를 해야겟네요