inflearn logo
강의

Khóa học

Chia sẻ kiến thức

React.js vừa tầm một miếng ăn: Từ cơ bản đến thực tiễn

새일기를 쓰면 한개가 아닌 두개가 등록이 됩니다ㅠ

Đã giải quyết

646

hwji

3 câu hỏi đã được viết

0

윈터로드님 알려주신 덕분에 완강할수잇었습니다ㅠㅠ 인프런 강의 첫 수강완료증을 받앗네요

제 프로젝트에 큰오류를 발견했습니다,,,, 새일기쓰면 똑같은게 2개가 만들어지는데 이거 어디서 오류를 수정해야 하는지알수잇을까요?

react javascript node.js nodejs

Câu trả lời 1

0

winterlood

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

완강하셨다니 감사합니다 그리고 축하드립니다!

코드를 보지 않고는 오류를 찾기 어렵습니다 🥲

오류가 발생한 코드를 코드샌드박스 또는 깃허브에 업로드 하신 다음 링크로 공유 부탁드립니다.

0

hwji

제가 깃허브랑 코드샌드박스 사용법을 잘몰라서 소스만 공유하겠습니다ㅠ 깃허브도 공부를 해야겟네요

0

hwji

//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;

1

winterlood

hwji님 안녕하세요 이정환입니다.
아무래도 모든 파일의 내용을 확인해야 정확한 오류를 찾을 수 있기 때문에 지금 올려주신 코드만으로는 정확한 파악이 어렵습니다
오류의 원인이 올려주신 두 파일(App, Editor)에 존재할 수도 있겠지만 혹여나 아닐 수도 있거든요

코드샌드박스 활용법이 어렵다면 제 메일로 전체 프로젝트 폴더(node_modules는 제거해주세요)를 압축해 보내주세요 그럼 제가 다운로드하고 환경을 설정한 다음 확인해 어떤 부분에 오류가 있는지 정확히 찾아서 알려드릴 수 있을 것 같습니다.

아래 메일 주소로 보내주시면 확인해보겠습니다.

king199777@gmail.com

0

hwji

구글이랑 카카오메일로 보냈습니다

확인해주시면 감사하겠습니다!

useEffect와 lifecycle문의

0

3

1

프론트엔드 학습 수준 문의

0

22

2

리액트 챕터별 코드에서 eslint 설정파일이 없어요

0

40

2

데이터 로딩중 화면만 계속 나와요!!

0

51

2

퍼블리셔일경우 어느정도 수준까지 강의를 들어야할까요

0

75

2

이후의 커리큘럼 문의

0

101

2

실슬환경 설정에서 save후 console.log 부분이 새로고침이 안되는현상입니다.

0

49

2

최적화 관련 질문있습니다 (useMemo 등)

0

82

3

프로바이더 컴포넌트의 위치는 어떤 기준인가요?

1

79

3

Date 객체에 관련하여 질문드립니다.

0

82

2

리액트 개정판 교재 질문

0

58

2

예제코드가 안나와요!

0

75

2

select a variant 선택에서 javascript와 javascript+react compiler 중 무엇을 선택해야하나요? com

0

104

2

onMouseEnter 관련 문의 드립니다

0

89

3

배열의 렌더링 관련 질문 드립니다.

0

70

2

2:40초 refObj를 콘솔로 출력시 오류가 발생합니다.

0

111

2

TS, 리액트 강의중에 뭘 먼저 수강하는게 좋을까요?

0

131

2

useCallback 적용한 onCreate, onUpdate, onDelete 함수..

0

66

1

vs code 자동완성관련 문의

0

106

2

91강 useEffect내에서 상태변화함수 호출시 발생하는 에러

1

173

2

87강 필터 함수 질문

0

65

2

useRef, useState count 비교

0

64

2

안된다고했던 이유가 무엇이었는지 모르겠습니다

0

86

2

85강에서 객체를 왜 클래스로 만들어서 new 하지 않는건지 궁금합니다.

0

73

2