48,400원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
firebase.json 저장이 되지 않아요!
firebase.json에 site 작성을 하고 저장을 하면 저장이 되지않습니다.sudo로 저장하기로 하여도 저장이 되지않고 오류가 발생합니다..맥북 M1으로 작업하고 있습니다.!
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
Context 질문드립니다.
안녕하세요 선생님. 질문이 있어요. 그전까지는 이해가 되었는데 Context강의가 유독 어렵네요... 먼저 DiaryStateContext.Provider의 value로 {data, onCreate, onRemove} 이렇게 넣으면 prop이 바뀌면 재생성된다는 것이 이해가 안되요. onCreate랑 onRemove는 useCallback으로 재생성 되는 것을 막아 놓은 것 아니었나요? 헷갈리네요. 두번째로 중첩으로 하는 이유가 잘 이해가 안 됩니다. 왜 중첩으로 하면 이게 해결이 될까요? 어차피 memoizedDispatches로 useMemo를 썼으면 그냥 DiaryStateContext.Provider에 value로 넣으면 안되는 건가요. 중첩으로 하는 이유가 잘 납득이 안됩니다. DiaryStateContext.Provieder value={data, memoizedDispatches} 이렇게 하면 안되나요? 그리고 useMemo로 묶는 부분도 다시 한번 설명해주실 수 있나요? useCallback으로 막아놨는데 왜 useMemo로 다시 묶어야 할까요 그냥 onCreate, onRemove, onEdit을 묶지 말고 따로따로 DiaryStateContext.Provider의 value로 {data, onCreate, onRemove} 이렇게 보내주면 안될까요? 강의를 두번 반복했는데도 잘 이해가 안되네요..
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
중첩 Context 관련 질문있습니다.
안녕하세요 중첩 Context 관련해서 질문하나 드립니다 <DirayStateContext> 라는 컨텍스트 또한 컴포넌트 이기에 data 값이 바뀌면 하위 컴포넌트 들 또한 재렌더링이 되기에 DirayStateContext 에 상태변경 함수를 넣어주게 되면 함수또한 재생성이되서 전달이 되는것이고 그러면 최적화가 풀려버리기에 그하위에 별도의 컨텍스트를 생성해서 data 라는 상태가 변경되어도 DiaryDispatchContext에 전달한 상태변경 함수는 변동이 없어서 최적화를 유지할 수 있다 제가 이해한게 맞는걸까요? 이부분이 살짝 헷갈립니다.
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
후속강의
안녕하세요 후속강의에 대해서 궁금해서 여쭤봅니다. 후속강의의 주제, 후속강의 출시 예상 시기가 궁금합니다. 이제 강의 시작하지만 그냥 궁금해서요 ㅎㅎ
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
수정하기(/edit) 페이지에서 이미지가 제대로 나타나지 않습니다!
안녕하세요 🙋♂️한 입 크기로 잘라먹는 리액트 강사 이정환 winterlood입니다!물론 질문은 수강생 여러분들 편하게 해 주시면 되지만!아래의 몇 가지 규칙만 지켜주시면 더 빠르고 정확한 답변을 드릴 수 있습니다!- 개인적인 고민 상담도 받아드립니다 :)- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요! 최종 프로젝트 edit 페이지 구현하다가 감정 이미지가 제대로 나타나지 않아서 질문드립니다! 강사님처럼 DiaryEditor 컴포넌트를 만들어서 new 페이지랑 edit 페이지에 공통으로 사용하였는데, new 페이지에서는 잘 나오는 이미지가 edit 페이지에서는 제대로 안 나오더라구요. 그리고 diary 컴포넌트에서도 이미지가 나오지 않습니다.. emotionList의 img 경로에 문제가 있는 걸까요? 저와 비슷한 질문을 남기신 분께 process.env 를 수정하셔야 할 거 같다고 강사님이 답변을 남기셨던던데, 제가 그것만 보고는 어떻게 수정을 해야할지 잘 감이 오지 않아 코드 샌드박스로 코드 남깁니다! codesandbox-url 감사합니다!
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
3:35부분에 질문이요!
3:35부분에 alert("없는 일기입니다."); 넣었을때 왜 alert을 두번 호출할까요ㅜㅜ?
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
조건문 업그레이드 질문.
그런데, 음식이 하나면 다행인데요~ 만약에 한식 : "불고기"에서 뭐 비빔밥, 전, 이런것들도 추가를 하고 싶을 때는 어떻게 하죠? :)
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
질문이 있습니다.
const handleChangeState = (e) => { console.log(e.target.name) console.log(e.target.value) setState({ ...state, [e.target.name]: e.target.value, // }) } 여기서 e.target.name을 배열에 넣는 이유가 궁금합니다.
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
data와 onCreate, onRemove, onEdit 을 같은 context에서 전달하면 안되는 이유
안녕하세요 🙋♂️한 입 크기로 잘라먹는 리액트 강사 이정환 winterlood입니다!물론 질문은 수강생 여러분들 편하게 해 주시면 되지만!아래의 몇 가지 규칙만 지켜주시면 더 빠르고 정확한 답변을 드릴 수 있습니다!- 개인적인 고민 상담도 받아드립니다 :)- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요! 6섹션 가장 마지막 강의인 '컴포넌트 트리에 데이터 공급하기 - Context' 강의 수강 중에 이해되지 않는 부분이 있어 질문 드립니다. (밑의 코드는 강사님께서 코드샌드박스로 올려주신 코드입니다!) import React, { useCallback, useEffect, useMemo, useReducer, useRef, createContext } from "react"; import DiaryEditor from "./DiaryEditor"; import DiaryList from "./DiaryList"; import "./App.css"; export const DiaryStateContext = createContext(null); export const DiaryDispatchContext = createContext(null); const reducer = (state, action) => { switch (action.type) { case "INIT": { return action.data; } case "CREATE": { const created_date = new Date().getTime(); const newItem = { ...action.data, created_date }; return [newItem, ...state]; } case "REMOVE": { return state.filter((it) => it.id !== action.targetId); } case "EDIT": { return state.map((it) => it.id === action.targetId ? { ...it, content: action.newContent } : it ); } default: return state; } }; const App = () => { const [data, dispatch] = useReducer(reducer, []); const dataId = useRef(0); const getData = async () => { setTimeout(async () => { const res = await fetch( "https://jsonplaceholder.typicode.com/comments" ).then((res) => res.json()); const initData = res.slice(0, 20).map((it) => { return { author: it.email, content: it.body, emotion: Math.floor(Math.random() * 5) + 1, created_date: new Date().getTime(), id: dataId.current++ }; }); dispatch({ type: "INIT", data: initData }); }, 2000); }; useEffect(() => { getData(); }, []); const onCreate = useCallback((author, content, emotion) => { dispatch({ type: "CREATE", data: { author, content, emotion, id: dataId.current } }); dataId.current += 1; }, []); const onRemove = useCallback((targetId) => { dispatch({ type: "REMOVE", targetId }); }, []); const onEdit = useCallback((targetId, newContent) => { dispatch({ type: "EDIT", targetId, newContent }); }, []); const memoizedDiaryAnalysis = useMemo(() => { const goodCount = data.filter((it) => it.emotion >= 3).length; const badCount = data.length - goodCount; const goodRatio = (goodCount / data.length) * 100.0; return { goodCount, badCount, goodRatio }; }, [data.length]); const { goodCount, badCount, goodRatio } = memoizedDiaryAnalysis; const store = { data }; const memoizedDispatch = useMemo(() => { return { onCreate, onRemove, onEdit }; }, []); return ( <DiaryStateContext.Provider value={store}> <DiaryDispatchContext.Provider value={memoizedDispatch}> <div className="App"> <DiaryEditor /> <div>전체 일기 : {data.length}</div> <div>기분 좋은 일기 개수 : {goodCount}</div> <div>기분 나쁜 일기 개수 : {badCount}</div> <div>기분 좋은 일기 비율 : {goodRatio}%</div> <DiaryList /> </div> </DiaryDispatchContext.Provider> </DiaryStateContext.Provider> ); }; export default App; data와 onCreate, onRemove, onEdit 함수를 같은 context의 props로 넘겨주게 되면 data가 변경될 때마다 세개의 함수들도 리렌더링 되어서 최적화가 풀리게된다고 하셨는데 이 부분이 잘 이해가 되지 않습니다. Provider도 하나의 컴포넌트라서 props가 바뀌면 재생성 되고, 하위 컴포넌트도 다시 재생성이 된다고 하셨는데, <DiaryDispatchContext.Provider>도 <Diary StateContex.Provider>의 하위 컴포넌트 아닌가요? 그래서 저는 상위 컴포넌트인 <Diary StateContext.Provider> 가 재생성 될 때 하위 컴포넌트인 <DiaryDispatchContext.Provider>도 재생성 되면서 리렌더링이 일어날 거 같다고 생각했습니다. 부모 컴포넌트가 리렌더링 되면 자식 컴포넌트도 같이 리렌더링 되니까요. 혹시 App 컴포넌트에서 세 개의 함수(onCreate, onRemove, onEdit)를 useCallback과 useMemo로 최적화를 해주었기 때문에 mount될 때만 생성이 되고 부모 컴포넌트인 <Diary StateContex.Provider>가 리렌더링 되더라도 <DiaryDispatchContext.Provider>는 리렌더링 일어나지 않는 건가요? 하지만 그렇다면 data와 함수를 같은 context로 전달해준다고 하더라도, 세 개의 함수를 최적화하기 위해 사용된 useCallback 에서 의존성 배열이 []로 전달되었으니 data의 state가 변경되어 리렌더링 되더라도 함수는 재생성 되지 않지 않을까 생각했습니다. 제가 어떤 점을 잘못 이해하고 있는 건지, 그리고 각각 다른 context로 넘겨주어야 하는 이유를 알려주시면 감사하겠습니다! 그리고 <DiaryDispatchContext.Provider> 가 <Diary StateContex.Provider>보다 상위에 와도 상관 없는지도 궁금합니다! 읽어주셔서 감사합니다!!
- 해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
글작성시 Home Context에는 추가되는데 State에는 안들어와요
https://github.com/Ina-dang/OneBiteReact/tree/master/emotiondiary 업데이트가 안돼요 ㅠㅠ...
- 해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
data에 값이 들어오지 않고, edit버튼을 누르면 게시글이 사라집니다.
안녕하세요, 마지막강의전에 발견된 문제 질문드립니다. 좋은강의 정말 감사합니다. 파이어베이스로 배포하면서 발견된 에러들이있는데 2시간가까이 삽질을 해도 원인을 찾기힘들어 질문 올립니다. 1.첫 로드시 로컬스토리지에 많은 데이터가 쌓여있음에도 리스트를 불러오지 못합니다. 로컬스토리지에는 데이터가 쌓여있지만 데브툴즈에는 아이템이 없다고 나와있었습니다. 데이터를 내려주는 App부터 체크하고 콘솔에 데이터가 찍히는걸 확인하고 그 하위 컴포넌트인 Home 페이지를 갔는데 여기에서 데이터가 빈값으로 나왔습니다. 분명 setData로 diaryList를 필터한값을 상태변환 시켜주었는데 data에 그 값이 반영되지 않고 계속 빈배열로 나옵니다. 원인이 무엇일까요? 2. 새 일기 쓰기를하면 일기가 써지고 로컬스토리지에 저장도 잘되고 화면에 로드도 됩니다. 그런데 일기를 수정하기화면에서 재작성해서 수정을 하면 리스트에서 일기가 제거됩니다. 그러고 로컬스토리지를 보면 일기는 남아있고(수정된상태로) 데브툴즈에서는 일기아이템이 삭제됩니다. 스스로 해결을 해보려했지만, 원인을 찾기힘들어 결국 질문 드립니다. 깃주소와 이미지를 남겨드립니다. https://github.com/iamoki/emotion-diary
- 해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
새 일기를 쓰면 2개씩 등록되는 이유가 뭘까요?
안녕하세요 강의를 너무 잘 봤고 많이 배웠습니다. 감사합니다. 그런데 다 작성하고 새 일기쓰기를 하니 매번 똑같은 글이 2개씩 생성됩니다. 데브툴즈에서 값을 확인해도 똑같은 내용으로 id 다른값으로 순서대로 2개가 생성됩니다. 인터넷에 찾아보고 이건가 싶은걸 따라해봐도 해결이 되지않아 질문과함께 레포지토리주소 남깁니다. https://github.com/iamoki/emotion-diary
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
함수로 나타내는 방법
안녕하세요! 체계적인 수업 덕분에 완강 후 스스로 react 공부를 시작하게 되었습니다. 공부하던 중, history 가 있는 dummy list를 만들었고, 이를 history 컴포넌트에서 사용하려고 합니다 보시는 바와 같이 /를 기준으로 나눠서 li태그로 나눠주려고 한 것인데, 이를 함수로 나타내려고 하니, ~ is not a function 오류가 뜨면서 계속 원하는대로 나오지 않았습니다. return 함수에서 직접 코딩하여 해결은 했지만, 왜 const 로 함수를 만들어서 사용했을 때는 동작하지 않았는지, 그 함수를 동작하게 하려면 어떤 코드를 짜야하는지 궁금합니다! (return 문에서 해결) (실패한 함수) 감사합니다! 좋은 하루 보내세요 :)
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
작성완료 버튼 후 onCreate is not a function 에러
안녕하세요. 동영상보고 따라하는데, 마지막 에러가.. 도무지 왜 나는지 알수가없습니다. 확인 좀 부탁드려요.. DiaryEditor.js import { useState, useRef, useContext } 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'; //PUBLIC_URL 실해잉 안된다면, const env = process.env; env.PUBLIC_URL = env.PUBLIC_URL || ''; 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:'끔찍함', }, ] const getStringDate = (date) => { return date.toISOString().slice(0,10); //toISOString->IOS 스트링을 반환해준다. YYYY-MM-DDTH -> slie잘라서 가져온다 } const DiaryEditor = () => { const contentRef = useRef(); const [content, setContent] = useState(''); const [emotion, setEmotion] = useState(3); //기본3번쨰 감정 const {onCreate} = useContext(DiaryDispatchContext); const handleClickEmote = (emotion) =>{ setEmotion(emotion); } const [date, setDate] = useState(getStringDate(new Date())); const navigate = useNavigate(); const handleSubmit = () => { if( content.length < 1 ){ contentRef.current.focus(); return; } //onCreate함수를 불러와야한다. onCreate(date, content, emotion); //navigate('/', {replace:true}); //option, 뒤로가기버튼을 못오게막는다 } return( <div className='DiaryEditor'> <MyHeader headText={'새 일기쓰기'} leftChild={ <MyButton text={'< 뒤로가기'} onClick={()=>navigate(-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={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; App 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) => { 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; } return newState; }; export const DiaryStateContext = React.createContext(); export const DiaryDispatchContext = React.createContext(); const dummyData = [ { id:1, emotion:1, content:'오늘의 일기 1번', date : 1659555437823, //console.log(new Date().getTime()); 값 확인해서 넣기 }, { id:2, emotion:2, content:'오늘의 일기 2번', date : 1659555437824, }, { id:3, emotion:3, content:'오늘의 일기 3번', date : 1659555437824, }, { id:4, emotion:4, content:'오늘의 일기 4번', date : 1659555437824, }, { id:5, emotion:4, content:'오늘의 일기 5번', date : 1759555437824, }, ] const App = () => { const [data, dispatch] = useReducer(reducer, dummyData); 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, content, date, 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/>} /> </Routes> </div> </BrowserRouter> </DiaryDispatchContext.Provider> </DiaryStateContext.Provider> ); }; export default App;
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
useCallback이 적용되지 않습니다..
안녕하세요. 강의를 따라서 차근차근 진행해 봤는데, 어느부분이 잘못된 것인지 useCallback이 적용되지 않습니다. useCallback을 onRemove와 onEdit파일에 적용했는데도 일기 목록을 삭제하면 삭제한 일기 다음 id 부분부터 또 전부 재 랜더링 됩니다. (예를 들어 4번 일기를 삭제하면 5번 부터 19번까지 재 랜더링됩니다) 강의 소스코드를 비교해보려고 했는데 이 강좌부분은 소스코드 링크가 누락되어있는지 보이지가 않네요.. 강의를 2번 3번 돌려봤지만 잘못된 부분이 무엇인지 찾기가 힘들어 질문 남김니다. 해당부분 작성한 전체코드가 업로드된 깃 Repository주소 남깁니다 https://github.com/minsumim/question.git
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
warning 해결 질문
코드샌드박스에서도 똑같은 warning이 발생하는데 이 warning이 발생하는 이유와 해결방법을 알 수 있을까요???
- 해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
input의 name값
안녕하세요! 강의 잘 보고 있습니다. <input name="author" value={state.author} ...~~ > 에서 name은 {state.author} 로 값을 쓰면 안되는지 궁금합니다.
- 해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
App -> Container prop전달 질문입니다
안녕하세요 🙋♂️한 입 크기로 잘라먹는 리액트 강사 이정환 winterlood입니다!물론 질문은 수강생 여러분들 편하게 해 주시면 되지만!아래의 몇 가지 규칙만 지켜주시면 더 빠르고 정확한 답변을 드릴 수 있습니다!- 개인적인 고민 상담도 받아드립니다 :)- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. children 으로 받아준다고 하셨는데 이게 항상 children 으로 넘겨주고 받는건가요? children 말고 cccc 마음대로 받았더니 Container 박스만 렌더링 되네요
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
23:05 select의 value={value} 질문입니다.
질문이있는데 select부분에 value={value} 이부분은 왜하는건가요? onchange={e => onChange(e.target.value} 에서 e.target.value는 option의 value={value}를 의미하는건알겠습니다. 그렇다면 option에 value만넣어저도 제가한 코드에서는 정상작동하는데 select의 value는 없애도되는건가요? http://colorscripter.com/s/vSMyU07 제가한 코드도 첨부합니다.
- 미해결[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
8:10 부분에서 왜 createContext사용할때 export로 내보내야하나요?
안녕하세요 8:10쯤에 context api사용하기위해서 createContext를 호출하는건 이해가 갔습니다. 근데 같은 App.js파일내에서 DiaryStateContext를 사용하는건데 왜 export로 내보내줘야하나요?