묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실무 중심! FE 입문자를 위한 React
학습노트 실습코드 링크 수정해주세요.
학습노트 pdf에서 4-2 실습코드 링크와 4-3 실습 코드 링크가 동일합니다. 수정 부탁드립니다. 그리고 5-1 강의에서 HTML과 리액트의 onclick/onClick 설명해주시는 화면에 둘 모두 onclick으로 되어 있음을 제보 드립니다.
-
미해결실무 중심! FE 입문자를 위한 React
SuryveyPie 기획서 어디에 있나요?
제목 그대로 SurveyPie 기획서 pdf를 어디서 받아야 하는지 모르겠습니다.처음에 받은 "학습노트_리엑트기초심화.pdf" 파일에서는 디자인 가이드와 코드만 존재합니다. 기획서 어디서 받을 수 있는지 알려주시면 감사하겠습니다.
-
미해결실무 중심! FE 입문자를 위한 React
swr과 recoil을 같이 쓰려면 어떻게 쓰면 될까요?
안녕하세요. 유익한 강의 감사합니다. 강의를 다 듣고나니 recoil 과 swr을 같이 쓰고 싶다는 생각이 들어서 redux를 썼던 admin 페이지를 swr과 recoil 조합으로 만들어보다가 막혀서 질문드립니다.. pages/ListPage.js에서 const { data, error, mutate } = useSWR( "/surveys?_sort_id&_order=desc", fetcher, ); const [survey, setSurvey] = useCurrentQuestion(); // recoil setSurvey(data);이렇게 swr로 불러온 데이터를 set으로 넣어주고 다른 페이지에서 recoil로 데이터를 불러서 써도 되는지 궁금합니다. 아니면 커스텀 훅에서 swr을 사용해도 괜찮을까요?
-
미해결실무 중심! FE 입문자를 위한 React
setAnswers 에 함수가 들어가도 괜찮은건가요?
안녕하세요. 유익한 강의 감사합니다.const useCurrentAnswer = () => { const step = useStep(); const [answers, setAnswers] = useRecoilState(answersState); const answer = answers[step]; const setAnswer = (newAnswer) => { setAnswers((answers) => { // 새로운 답변 렌더링 (answers 는 그냥 변수명 ) const newAnswers = [...answers]; // 기존 답변목록을 복붙함 (불변성의 법칙을 지켜라 / 기존 데이터는 건들지마..) newAnswers[step] = newAnswer; // 새로 작성한 답변을 복붙한 배열에 넣어줌 return newAnswers; // 새로운 답변 목록 반환 }); }; return [answer, setAnswer]; };에서 answer - String / 답변answers - String[] / 답변 목록 setAnswer - answer를 렌더링해주기위한 함수 / setAnswer(param) { answer = param }setAnswers - answers를 렌더링해주기위한 함수 / setAnswers(param) { answers = param } 로 이해되는데 그렇다면 setAnswers에 함수가 들어가도 괜찮은건지 궁금합니다. setAnswers((answers) => { const newAnswers = [...answers]; newAnswers[step] = newAnswer; return newAnswers; });는 setAnswers(화살표함수) { answers = 화살표함수} 이고answers는 화살표함수가 되는게 아닌가요? answers는 함수가 되어 입력된값을 리턴해서 바로 answers에 할당되는건가요?아니면setAnswers에서 함수가 실행되어 리턴된 값이 answers에 할당되는 건가요??
-
미해결실무 중심! FE 입문자를 위한 React
4-3 클래스코드를 찾을 수가없습니다
4-3 아코디언 컴포넌트 만들기 실습 코드를 찾을 수 가없습니다 . 4-2코드 링크가 4-3 페이지에 들어있던데 수정부탁 드릴게여!
-
미해결실무 중심! FE 입문자를 위한 React
아래 랭크좀 보는법좀 알려주세요
코드 샌드박스링크를 알고 싶은데 자꾸 아래를 보래요 ㅠ근데 안보입니다ㅠㅠ
-
미해결Slack 클론 코딩[실시간 채팅 with React]
SWR or axios 관련 질문이 있습니다.
프론트에서 백앤드 서버로 네트워크 요청시 요청 헤더에 보면 Connection: keep-alive 라고 표기 되는데 이 상태의 요청들이 많으면 서버가 부하가 큰다던가 할 수 있는 요지가 있을까요?프론트에서 보내는 저 api 상태의 요청이 많으면 문제가 생길수 있다는데프론트에서 요청시 팬딩이 걸리는 그런 상황에 요청을 끊을 수 있는 방법이 있을까요?(백엔드 서버에 어떻게히면 부담을 줄일수 있을까 고민중입니다;)
-
미해결Slack 클론 코딩[실시간 채팅 with React]
캐싱 궁금한점
새로 요청 보내는게 아니라 캐싱된 값을 사용한다구 하셨는데 강의내에서 '/api/users' 요청만 dedupingInterval 2초동안 캐싱되는 거고 `/api/workspaces/${workspace}/channels` 요청은 재요청 하는 것으로 이해해서 실습해보니 첫 실행시 users, channels, members 요청이 한번씩 실행되되고 이후에 2초간 캐싱 되는 건 refetchOnMount 같이 아예 다른 탭에 갔다가 돌아오는 경우 인 것 같습니다. 아무래도 제가 이해한 캐싱과 강의에서 말하는 캐싱이 다른 것 같아 질문남깁니다. 강의 경우 처럼 한 컴포넌트 내에서 useSWR 혹은 react-query의 useQuery를 사용하는 경우 자식 컴포넌트에서 사용하는 useQuery가 캐싱된 데이터를 사용한다고 이해해도 될까요?
-
미해결Slack 클론 코딩[실시간 채팅 with React]
useSwrInfinite 질문입니다.
안녕하십니까 제로초님 슬랙 클론코딩 강의를 보고 실시간 챗을 구현해보고 있습니다. useSwrInfinite를 사용하여 구현하고 있고, 요청주기에 대해 궁금한점이 생겼습니다. useSwr은 DedupingInterval을 사용해서 설정한 주기 동안은 탭 변환이 일어나도 재요청을 보내지않고 캐시된 값을 그대로 사용하는 것으로 이해하고 있습니다. 그런데 useSwrInfinite의 요청 주기를 잘 모르겠어서 공식문서를 읽어보니 initialSize = 1: 초기에 로드해야 하는 페이지의 수 revalidateAll = false: 항상 모든 페이지의 갱신 시도 revalidateFirstPage = true: always try to revalidate the first page persistSize = false: 첫 페이지의 키가 변경될 때, 페이지 크기를 1(initialSize가 설정된 경우 initialSize)로 초기화하지 않음 챗을 쳐서 실시간으로 채팅이 화면에 그려질 수 있는이유는 초기에 initialSize = 1 로 설정되어 있어서 이차원 배열의 첫번째 배열이 갱신되어서 그런 것일까요? 챗을 칠때마다 갱신된 데이터를 get 할 수 있어서 좋지만 서버에 얼마만큼(어느주기로) 요청을 보내는지 알고 싶습니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
redux와 react-query 설정
다른 질문 들도 보다가 궁금한 점이 생겨 여쭤봅니다. 프로젝트에서 내에서 상태관리를 redux로 하고 server에서 데이터 패칭하는 부분을 (공부해 보니 server state라고 부르더군요) react-query(또는 swr)로 사용하려는 경우 설정을 어떻게 해야하나 궁금해서 검색해봤는데 마땅한 자료가 없어서 질문드려요 CRA기준으로 index.js에 import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import reducer from "./reducer"; import { Provider } from "react-redux"; import { configureStore } from "@reduxjs/toolkit"; import { Global } from "@emotion/react"; import { GlobalStyle } from "./index.style"; import { QueryClientProvider, QueryClient } from "react-query"; const store = configureStore({ reducer }); const queryClient = new QueryClient(); ReactDOM.render( <Provider store={store}> <QueryClientProvider client={queryClient}> <App /> <Global styles={GlobalStyle} /> </QueryClientProvider> </Provider>, document.getElementById("root") ); 이런식으로 사용해서 reducer 함수 정의하고 각 컴포넌트에서 queryClient를 import해서 사용하는 건가요? 제로초님 강의 들으면서 react-query를 이제 막 공부하고 있는데 react-query가 내부적으로 contextAPI 사용한다고 알고있는데 redux랑 contextAPI를 같이 쓴다는게 정확히 감이 안잡히네요 제가 잘못알고 있는 부분이나 공부해야할 키워드를 알려주시면 감사하겠습니다.
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
강의소개에서
강의소개보면 swr(리덕스대체) 라고 나와있는데 swr도 리덕스처럼 상태관리를 하는건가요?
-
미해결Slack 클론 코딩[실시간 채팅 with React]
swr 관련 질문입니다.
SWR 관련 질문입니다. 1.x 사용 했을 때 mutate를 적용을 시켜 봤습니다. 강의 초반부에 로그 아웃 버튼을 달고 화면만 띄우고 swr로 불러온 데이터를 찍으면 /api/users 데이터가 있는 것을 확인 할 수가 있는데 login 후 workspace/channel 들어가면서 console로 찍어보니 최초에는 데이터가 있는 것으로 나오는데 한번 더 렌더링이 되는건지 workspace : {id :...}workspace: undefined 이렇게 나오던데 어떤 식으로 접근하면 좋을지 문의 드립니다. 혹시 몰라서 let count = 0; 0 : workspace : {id :...}1 : workspace: undefined 식으로 카운팅도 해 봤는데지렇게 찍혀서 어떻게 접근을 해야할지 몰라 문의 드립니다.
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
swr상태관리시 다른 컴포넌트 리렌더링 하는방법 문의
안녕하세요. swr관련 문의 드립니다. local state를 관리하는 용도로 swr을 사용해보고 있습니다. 컴포넌트 구조는 Main아래 Overview아래 OverviewDut라는 컴포넌트를 두고있는데요. Main에서 Socket.io를 통해서 받아온 데이터를 OverviewDut에서 사용하려고 합니다. swr에서 관리하고 있는 값은 제대로 변경되고 있는데요. OverviewDut컴포넌트의 리렌더링이 되지 않습니다. 부모컴포넌트에서 swr의 상태가 바뀐경우 자식컴포넌트에서 리렌더링이 필요한 경우에 대해 문의드립니다. [useDuts.js] [Main.jsx] [OverviewDut.jsx]
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
로그인 & 회원가입 관련해서 질문드립니다.
로그아웃을 하는 작업은 cookie의 값을 지우면 로그아웃이 된다고 하셨는데, 백엔드에 logout요청을 보내는 이유가 무엇인가요? 그리고 로그인 했을때 쿠키에 저장되는 방식은 어떤식으로 흘러가는 것인지 잘 이해가 가지 않습니다! 저는 로그인할때 서버에 로그인 요청을 하면 서버에서 토큰을 줘서 그 토큰을 프론트엔드 단에서 쿠키에 저장하는 방식을 사용했었는데 그 방식과는 다른 방식인가요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
강의듣고 SWR을 구현하려고 합니다.
강의듣고 SWR로 구현하려고 하는중에 질문드립니다. 조회 버튼을 눌렀을때 특정 상태값을 true로 바꾸로 swr로 호출합니다. 근데 계속해서 서버쪽을 반복해서 호출합니다. 이를테면 아래와 같이 호출합니다. 조회버튼 누를때는 useSWR이 실행되고 실행되지 않게 하는방법이 있습니까? 계속해서 response 304를 호출하고 있습니다. const { data: outboundProgressMasterData, error: outboundProgressMasterError } = useSWR(onData ? `http://localhost:3065/outbound/progressListMaster/${onData?.center_cd}/${onData?.cust_cd}/${onData?.start_date}/${onData?.end_date}/${onData?.query_index}` : null, fetcher);
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
swr관련 질문
안녕하세요 제로초님 ! 궁금한점이 있어서 문의 드립니다. swr이 리덕스를 대체 할 수 있다고 하셨는데.. 예를들어서 ..서버가 구축이 안된 상태에서는 swr를 활용할수 있는 방법이 없을까요 ? 이전 챕터에서 서버가 구축 안된상태에서는 faker를 사용해서 임시로 데이터들을 넣어주었는데 ..swr을 사용할 경우에는 어떻게 해야하나요 ?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
reducer함수에서 로컬 데이터에 find,filter,push등 해주는 이유가 궁금합니다.
안녕하세요 요즘 SWR과 redux를 섞어쓰고 있는 초보 학생입니다. 지식이 미약해서 부족한 질문이라도 들어주시면 감사하겠습니다. 리듀서 함수에서는 예를들면 이런 코드가 있으면 action.data를 mainPosts 맨앞에 둔다는 뜻인데 case ADD_POST_SUCCESS: draft.mainPosts.unshift(action.data); break; 이 코드는 프런트 환경에서 store에 있는 mainPosts에 action.data를 추가한다는 뜻으로 서버에 요청 상관없이 프론트 환경에서 새로고침 없이 view 변동을 보여주려고 쓰는 건가요? 저는 swr을 사용하면서 서버에서 mainPosts를 불러올때 데이터가 추가되면 mutate 로 체크를 해주었는데요. swr을 사용해서 data를 가져올 경우 굳이 전역스토어에 추가 게시글 데이터를 추가해야되는지?? 의문입니다. 그냥 서버에서 처리해주고 가져오면 되는거 아닌가? 이런 생각이 드는데 경험이 적다보니 아직 잘모르겠습니다. 그리고 선생님 최신강의를 보던중 swr로 전역상태를 관리할수있다는 말을 들었습니다. 근데 이기능은 react-query에 정식 릴리즈 되어있는것 같은데 이걸로 api 콜+전역상태관리 둘다 하게되면 굳이 리덕스를 사용하지 않아도 되는 걸까요?? 리덕스 세팅이나 코드량이 너무 긴 단점이 있지만 반면에 에러 헨들링은 쉽다는 장점이 있어? 의견을 여쭈어 보고싶습니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
reduxSaga로는 되는데 SWR로 바꾸면 에러가 나요
profil.js import React,{useEffect} from 'react'; import AppLayout from "../components/AppLayout" import NicknameEditForm from "../components/NicknameEditForm" import FollowList from "../components/FollowList" import {useSelector,useDispatch} from "react-redux" import {LOAD_FOLLOWERS_REQUEST,LOAD_FOLLOWINGS_REQUEST} from "../reducers/userReducer" import Head from "next/head" import {useRouter} from "next/router" import {END} from "redux-saga" import axios from "axios"; import wrapper from "../store/configureStore" import {LOAD_MY_INFO_REQUEST} from "../reducers/userReducer" import useSWR from "swr"; import {backAddress} from "../back" const fetcher = (url)=>axios.get(url,{withCredentials:true}).then(result=>result.data); function Profile(){ const dispatch = useDispatch(); const router = useRouter(); const {me} = useSelector(state=>state.userReducer); const {data:followersData,error:followerError} = useSWR(`${backAddress}/user/followers`,fetcher); const {data:followingsData,error:followingError} = useSWR(`${backAddress}/user/followings`,fetcher); useEffect(()=>{ if(!me) { router.push('/'); } },[me]) // useEffect(()=>{ // dispatch({ // type:LOAD_FOLLOWERS_REQUEST // }) // dispatch({ // type:LOAD_FOLLOWINGS_REQUEST // }) // },[]) // return 이 hooks(use...())보다 위에 있을수 없음 if(!me) return null; if(followerError || followingError){ console.error(followerError || followingError); return <div>팔로잉/팔로워 로딩 중 에러가 발생함</div>; } return ( <> <Head> <title>profile</title> </Head> <AppLayout> <NicknameEditForm /> <FollowList header="팔로잉 목록" data={followingsData} /> <FollowList header="팔로워 목록" data={followersData} /> </AppLayout> </> ) } export const getServerSideProps = wrapper.getServerSideProps(async (context)=>{ const cookie = context.req ? context.req.headers.cookie : ""; axios.defaults.headers.Cookie = ""; if(context.req && cookie){ axios.defaults.headers.Cookie = cookie; // 쿠키 넣기 } context.store.dispatch({ type:LOAD_MY_INFO_REQUEST, }) context.store.dispatch(END); // 사용법 request success 기다리기 await context.store.sagaTask.toPromise(); // 사용법 configureStore.js 에서 등록한 sgagTask 를 사용 }); export default Profile; routes/user.js router.get("/followers",isLoggedIn,async (req,res,next)=>{ try{ const me = await User.findOne({where:{id:req.user.id}}); if(!me){ res.status(403).send("me 없음") } const followers = await me.getFollowers( { limit:2, } ); res.status(200).json(followers) } catch(error){ console.error(error); next(error); } }) router.get("/followings",isLoggedIn,async (req,res,next)=>{ try{ const me = await User.findOne({where:{id:15||req.user.id}}) if(!me){ res.status(403).send("me 없음") } const getFollowings = await me.getFollowings( { limit:2, } ); res.status(200).json(getFollowings) } catch(error){ console.error(error); next(error); } }) Error sql: 'SELECT `User`.`id`, `User`.`email`, `User`.`nickname`, `User`.`createdAt`, `User`.`updatedAt`, `Posts`.`id` AS `Posts.id`, `Followings`.`id` AS `Followings.id`, `Followings->Follow`.`createdAt` AS `Followings.Follow.createdAt`, `Followings->Follow`.`updatedAt` AS `Followings.Follow.updatedAt`, `Followings->Follow`.`FollowingId` AS `Followings.Follow.FollowingId`, `Followings->Follow`.`FollowerId` AS `Followings.Follow.FollowerId`, `Followers`.`id` AS `Followers.id`, `Followers->Follow`.`createdAt` AS `Followers.Follow.createdAt`, `Followers->Follow`.`updatedAt` AS `Followers.Follow.updatedAt`, `Followers->Follow`.`FollowingId` AS `Followers.Follow.FollowingId`, `Followers->Follow`.`FollowerId` AS `Followers.Follow.FollowerId` FROM `Users` AS `User` LEFT OUTER JOIN `Posts` AS `Posts` ON `User`.`id` = `Posts`.`UserId` LEFT OUTER JOIN ( `Follow` AS `Followings->Follow` INNER JOIN `Users` AS `Followings` ON `Followings`.`id` = `Followings->Follow`.`FollowingId`) ON `User`.`id` = `Followings->Follow`.`FollowerId` LEFT OUTER JOIN ( `Follow` AS `Followers->Follow` INNER JOIN `Users` AS `Followers` ON `Followers`.`id` = `Followers->Follow`.`FollowerId`) ON `User`.`id` = `Followers->Follow`.`FollowingId` WHERE `User`.`id` = NaN;', parameters: undefined } SequelizeDatabaseError: Unknown column 'NaN' in 'where clause' at Query.formatError (C:\WEB\full\back\node_modules\sequelize\lib\dialects\mysql\query.js:239:16) at Query.run (C:\WEB\full\back\node_modules\sequelize\lib\dialects\mysql\query.js:54:18) at processTicksAndRejections (internal/process/task_queues.js:97:5) GET /user/followers 500 27.011 ms - 511 리덕스사가로 바꿔서 실행하면 잘 작동하는데 swr로 바꾸면 sql문에 nan값이 들어갑니다. 제가 잘못한 부분이 어디인가요?