묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결처음 만난 리액트(React)
false expression
Inline If에서 false expression을 사용하면 뒤에 내용은 평가되지 않지만, false expression의 결과 값이 그대로 리턴되기 때문에 주의 해야 한다 이렇게 말씀하셨는데 그러면 하단의 흰색 박스에 조건이 만족하지 않을 경우에도 결과 값을 그대로 리턴하나요..?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
refetchQueries 질문
안녕하세요.강의를 복습하던 도 중 궁금한게 생겨서 질문 드립니다.onClick={qqq}으로 버튼을 클릭시 5개 정도의 데이터가 refetchqueries 되어야 하는데 모두 다 쓰면 비효율적 인 듯 합니다.많은 데이터가 refetch되어야 할 때 페이지가 새로고침 되는것이 낫다고 생각 하는데.. 1.새로고침을 한다면 어떤식으로 코드를 써야하나요?2. 둘 중 어느것이 더 효율적일까요.
-
미해결처음 만난 리덕스(Redux)
todo 추가, 삭제, 모두삭제는 되는데 devtools에서 변화가 없어요
기능은 동작하는데 devtools에 state, diff 에서 정상적으로 나오지 않습니다.. 뭐가 문제일까요?
-
해결됨처음 만난 리덕스(Redux)
안녕하세요, Counter 애플리케이션 실습 부분에서 질문있습니다!
function render() { valueEl.innerHTML = store.getState().toString(); } render(); // redux store에 변화가 있을 때마다 render 함수를 호출한다. store.subscribe(render);정말 별건 아니지만 store.subscribe(render) 부분이 그냥 문맥 상 읽으면 store가 render를 구독한다 의 표현이 되는데, 코드 상의 흐름은 store의 변화에 따라 render가 실행되니 render가 store를 구독하는 걸로 이해했습니다. 이게 맞는지 궁금합니다.
-
미해결처음 만난 리액트(React)
state.notifications 배열에 push가 가능한지 질문드리겠습니다.
const { notifications } = this.state; const index = notifications.length; notifications.push(reservedNotifications[index]); this.setState({ notifications: notifications })위 코드에서 state.notifications 배열에 바로 push를 해서 setState를 해줬는데지난 강의에서는 state에 있는 배열 또는 객체를 직접 수정하지 않고 복사해서newNotifications = [...notifications] 처럼새로 할당 한 다음 setState를 해준다고 봤던 부분이 있어서 어떤 경우에는 직접 state배열에 push가 가능한지 질문 드려도 괜찮을까요 강의 잘 보고 있습니다. 감사합니다!
-
미해결지금 바로 React 시작하기
React에서 이벤트 처리하기(추가퀴즈)
교안 [참고할만한 자료]도 읽어보고 고민을 해보았는데추가퀴즈에 대한 정답에 대한 방향성을 모르겠어요import { useState } from "react"; function App() { return <div>{user.login ? <HomePage /> : <Login />}</div>; } function HomePage() { return ( <div> <h1>Welcome {user.nickname}</h1> <button>로그아웃</button> </div> ); } let user = { login: false, id: "dw", pw: "1234", nickname: "june", }; function Login() { const [id, setId] = useState(""); const [pw, setPw] = useState(""); const handleLoginSubmit = (e) => { e.preventDefault(); if (id === "") { alert("아이디를 입력하지 않았습니다."); } else if (pw === "") { alert("패스워드를 입력하지 않았습니다."); } else { if (id === user.id && pw === user.pw) { alert("로그인 성공"); user.login = true; } else { alert("잘못된 정보"); } } console.log(user.login); }; const handleLoginInput = (e) => { setId(e.target.value); }; const handlePasswordInput = (e) => { setPw(e.target.value); }; return ( <form onSubmit={handleLoginSubmit}> <label> 아이디 : <input type="text" onChange={handleLoginInput} /> </label> <br /> <label> 비밀번호 : <input type="password" onChange={handlePasswordInput} /> </label> <button type="submit">로그인</button> </form> ); } export default App;
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
api 질문입니다.
포토폴리오 마이페이지 - 내포인트 부분을 작업하는 도중 api 질문입니다.fetchPointTransactionsOfBuying 이 내포인트 -> 구매내역 api로 알고있습니다.피그마를 보면 거기서 판매자 데이터를 가져오고있는데 오류가 뜨네요.ㅠ판매자 데이터를 가져오고 싶은데 여기서 seller {name} 이부분을 넣으면 데이터가 안가져오네요..판매자데이터가 없어서 그런건지 왜 그런지와 어떻게 해야하는지 두가지 모두 알고싶습니다.
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
서버 켜는 명령어가 안 되요ㅜㅜ
안녕하세요. 서버 켜려고 back 폴더에서 npm run dev 하면 [nodemon] app crashed - waiting for file changes before starting...와 같은 에러가 나옵니다. node.js 버전은 18.16.1 입니다.결국 로컬호스트3095 들어가면:3095/l:1 GET http://localhost:3095/l 500 (Internal Server Error)이런 에러가 나오는데, 이건 서버 접속이 아예 안되었기 때문에 나오는 거겠죠..?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
redux thunk 원리 질문
1.thunk를 사용하면 함수형 action을 dispatch 했을때action을 단순히 실행하는 것으로 보이는데요. 그렇다면 아래 두 코드처럼함수형 action을 dispatch하는 방식과 함수로 감싸지 않고 하는 방식과 결과는 같다고 생각되는데 맞나요?const loginAction = () => { return (dispatch) => { dispatch(loginRequestAction()); axios.post('/api/login') .then((res) => { dispatch(loginSuccessAction(res.data)); }) .catch((err) => { dispatch(loginFailureAction(err)); }) } } const onClickLogin = () => { dispatch(loginAction()); }const onClickLogin = () => { dispatch(loginRequestAction()); axios.post('/api/login') .then((res) => { dispatch(loginSuccessAction(res.data)); }) .catch((err) => { dispatch(loginFailureAction(err)); }) }2.1이 맞다면 함수 action을 dispatch하는 방식은 편의성 때문이라고 봐도 될까요?3.강의 10:40 쯤에 thunk는 한번에 dispatch를 여러번 할 수 있게 해준다고 하셨는데thunk없이 아래처럼 여러번 쓰는 것은 문제가 될 수 있나요?// action은 임의로 지었습니다 const onClickButton = () => { dispatch({type: 'CHANGE_ID'}); dispatch({type: 'CHANGE_PASSWORD'}); }
-
미해결처음 만난 리액트(React)
렌더링 관련 질문
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 소플님 실습을 따라 해보았는데 하나의 useEffect는 컴포넌트가 렌더링 될 때마다 콘솔이 찍히고 하나의 useEffect는 count값이 변경될 때마다 찍힌다는 것까지는 이해했습니다. 근데 마지막 최대 인원을 수용하는 10명까지 수용을 하고는 버튼 컴포넌트가 isFull: true로 찍히고 컴포넌트가 렌더링 되지 않아서 useEffect 콘솔과 isFull: true 이 안 찍혀야 하는 것 아닌가요? 왜 이렇게 찍히는지 이해가 안됩니다,,ㅠㅠ
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
Fly.io도 유료로 전환이 된걸까요
Fly.io 설치 후 홍콩으로 선택하는 지점(강의 4:17)에서 하기와 같은 오류가 뜨고있습니다.에러 내용이 Error: We need your payment information to continue! Add a credit card or buy credit: https://fly.io/dashboard/kimyr6868-gmail-com/billing 결제수단을 입력하는 내용으로 보아 진행이 어려울 것 같은데 이런 상황에선 어떻게 하면 좋을지 문의드립니다!
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
sequlize같은 orm에 대한 질문
javascript는 sequilize java는 JPA같은 데이터베이스를 다루는 ORM이 있는 것 같은데 ORM에 대해 좀더 찾아보니 sql 쿼리문을 직접 작성하는 것보다 코드의 양도 줄고 유지 보수도 더 쉬운 것 같습니다.나중에 sql 쿼리문을 직접 입력하는 방식을 배워야하나 생각이 들었지만 이렇게 장점이 많은 ORM을 안 쓸 이유가 없는 것 같고 나중에 다른 백앤드 프레임 워크 예를 들어 java Spring같은 것을 배워도 JPA같은 ORM을 배우지 sql 쿼리문을 직접 넣는 방식으로는 하지 않을꺼 같습니다.그럼에도 불구하고 sql 쿼리문을 직접 넣는 방식을 배워둘 필요가 있을까요? 아니면 ORM방식에 단점이 있을까요?
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
onClick 사용시 질문입니다!
onClick를 이용할경우 onClick= { ( ) => ?? } 해당 형식으로 사용해야하는 경우가 있고 아닌경우가 있는데 헷갈리네요 ㅜㅜ 클릭할떄 실행되는함수가 파라미터를 받지않는다면 onClick={함수명} 이런식이고 파라미터를 받는다면 onClick={( )=>함수명( 파라미터 )} 이런식인거같은데 다른경우도 있을까요?? 콜백 함수에 관한 영상을 찾아보면 이해가 될까요??
-
미해결Slack 클론 코딩[실시간 채팅 with React]
로그인 화면에서 리다이렉트 시 workspace 목록이 표시되지 않는 문제
안녕하세요. 강의 잘 듣고 있습니다. 다름이 아니라 login 한 후 workspace로 리다이렉트 된 후, workspace 목록이 아래와 같이 나타나지 않는 현상이 발생합니다. 하지만 다른 탭을 다녀오거나, workspace 추가를 하면 다시 정상적으로 아래와 같이 workspace 목록이 나타납니다. 아마 userData를 리다이렉트하면서 불러오지 않아 생기는 문제 같습니다. mutate()를 사용하고, dedupinginterval을 줄여도 문제 해결이 안되는 것 같아 리다이렉트됨과 동시에 다시 userData를 불러오도록 수정해야 할 것 같은데, 이를 구현할 수 있는 방법이 생각이 나지 않습니다. 현재 제 코드 일부 아래에 첨부합니다.App.jsconst App: FC = () => { return ( <Switch> <Redirect exact path="/" to="/login" /> <Route path="/login" component={LogIn} /> <Route path="/signup" component={SignUp} /> <Route path="/workspace/:workspace" component={Workspace} /> </Switch> ); };Login/index.tsxconst LogIn = () => { const {data, error, mutate} = useSWR('/api/users', fetcher, { dedupingInterval: 100000, }); const [logInError, setLogInError] = useState(false); const [email, onChangeEmail] = useInput(''); const [password, onChangePassword] = useInput(''); const onSubmit = useCallback( (e) => { e.preventDefault(); setLogInError(false); axios .post( '/api/users/login', { email, password }, { withCredentials: true }, ) .then((response) => { mutate(response.data, false); //Optimistic UI }) .catch((error) => { setLogInError(error.response?.status === 401); }); }, [email, password], ); if (data === undefined) { return <div>로딩중...</div>; } if (data) { return <Redirect to="/workspace/sleact/channel/일반" />; }Workspace/index.tsximport Menu from "@components/Menu"; import Modal from "@components/Modal"; import CreateChannelModal from "@components/CreateChannelModal"; import useInput from "@hooks/useinput"; import fetcher from "@utils/fetcher"; import axios from "axios"; import React, { FunctionComponent, useCallback, useState } from "react" import { Link, Redirect, Route, Switch, useParams } from 'react-router-dom'; import { toast } from 'react-toastify'; import useSWR from "swr"; import { AddButton, Channels, Chats, Header, LogOutButton, MenuScroll, ProfileImg, ProfileModal, RightMenu, WorkspaceButton, WorkspaceModal, WorkspaceName, WorkspaceWrapper, Workspaces } from "@layouts/Workspace/style"; import gravatar from 'gravatar'; import { Button, Input, Label } from '@pages/SignUp/style'; import { IChannel, IUser } from "@typings/db"; import loadable from "@loadable/component"; const Channel = loadable(() => import('@pages/SignUp')); const DirectMessage = loadable(() => import('@layouts/Workspace')); const Workspace: FunctionComponent = () => { const [showUserMenu, setShowUserMenu] = useState(false); const [showCreateWorkspaceModal, setShowCreateWorkspaceModal] = useState(false); const [showWorkspaceModal, setShowWorkspaceModal] = useState(false); const [showCreateChannelModal, setShowCreateChannelModal] = useState(false); const [newWorkspace,onChangeNewWorkspace, setNewWorkSpace] = useInput(''); const [newUrl, onChangeNewUrl, setNewUrl] = useInput(''); const { workspace } = useParams<{workspace: string}>(); const { data: userData , error, mutate} = useSWR<IUser | false>( '/api/users', fetcher, { dedupingInterval: 2000, } ); const { data: channelData } = useSWR<IChannel[]>( userData? `api/workspaces/${workspace}/channels` : null, fetcher ); const onLogout = useCallback(() => { axios .post('/api/users/logout', null, { withCredentials: true, }) .then(() => { mutate(false, false); }); }, []) const onClickUserProfile = useCallback((e) => { e.stopPropagation(); setShowUserMenu((prev) => !prev); }, []); const onClickCreateWorkSpace = useCallback(() => { setShowCreateWorkspaceModal(true); }, []); const onCreateWorkspace = useCallback((e) => { e.preventDefault(); if(!newWorkspace || !newWorkspace.trim()) return; if(!newUrl || !newUrl.trim()) return; axios .post( '/api/workspaces', { workspace: newWorkspace, url : newUrl, }, { withCredentials: true, }) .then(() => { mutate(); setShowCreateWorkspaceModal(false); setNewWorkSpace(''); setNewUrl(''); }) .catch((error)=>{ console.dir(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [newWorkspace, newUrl]); const onCloseModal = useCallback(() => { setShowCreateWorkspaceModal(false); setShowCreateChannelModal(false); }, []); if(!userData) { return <Redirect to="/login"/> } const toggleWorkspaceModal = useCallback(()=> { setShowWorkspaceModal((prev) => !(prev)); },[]); const onClickAddChannel = useCallback(() => { setShowCreateChannelModal(true); }, []); return ( <div> <Header> <RightMenu> <span onClick = {onClickUserProfile}> <ProfileImg src = {gravatar.url(userData.email, {s: '28px', d: 'retro'})} alt= {userData.nickname}/> {showUserMenu && ( <Menu style={{right:0, top:38}} show={showUserMenu} onCloseModal={onClickUserProfile}> <ProfileModal> <img src={gravatar.url(userData.email, {s: '36px', d: 'retro'})} alt= {userData.nickname}/> <div> <span id="profile-name">{userData.nickname}</span> <span id="profile-active">Active</span> </div> </ProfileModal> <LogOutButton onClick={onLogout}>로그아웃</LogOutButton> </Menu> )} </span> </RightMenu> </Header> <WorkspaceWrapper> <Workspaces> {userData?.Workspaces?.map((ws) => { return ( <Link key={ws.id} to={'/workspace/${123}/channel/일반'}> <WorkspaceButton>{ws.name.slice(0,1).toUpperCase()}</WorkspaceButton> </Link> ); })} <AddButton onClick={onClickCreateWorkSpace}>+</AddButton> </Workspaces> <Channels> <WorkspaceName onClick={toggleWorkspaceModal}> Sleact </WorkspaceName> <MenuScroll> <Menu show={showWorkspaceModal} onCloseModal={toggleWorkspaceModal} style={{ top: 95, left: 80}}> <WorkspaceModal> <h2>Sleact</h2> <button onClick={onClickAddChannel}>채널 만들기</button> <button onClick={onLogout}>로그아웃</button> </WorkspaceModal> </Menu> {channelData?.map((v) => (<div>{v.name}</div>))} </MenuScroll> </Channels> <Chats> <Switch> <Route path="/workspace/:workspace/channel/:channel" component={Channel} /> <Route path="/workspace/:workspace/dm/:id" component={DirectMessage} /> </Switch> </Chats> </WorkspaceWrapper> <Modal show={showCreateWorkspaceModal} onCloseModal={onCloseModal}> <form onSubmit={onCreateWorkspace}> <Label id="workspace-label"> <span>워크스페이스 이름</span> <Input id="workspace" value={newWorkspace} onChange={onChangeNewWorkspace}/> </Label> <Label id="workspace-url-label"> <span>워크스페이스 url</span> <Input id="workspace-url" value={newUrl} onChange={onChangeNewUrl}/> </Label> <Button type="submit">생성하기</Button> </form> </Modal> <CreateChannelModal show={showCreateChannelModal} onCloseModal={onCloseModal} setShowCreateChannelModal={setShowCreateChannelModal} /> </div> ) } export default Workspace
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
state is not defined 에러가 뜹니다
이 에러는 왜 발생한 건가요?구글에 검색도 해봤는데 안나오네요도와주세요 ㅠreducers/user.js 코드입니다export const initialState = { } export const loginAction = (data) => { return { type: 'LOG_IN', data, } } export const logoutAction = () => { return { type: 'LOG_OUT', } } const reducer = (State = initialState, action) => { switch (action.type) { case 'LOG_IN': { return { ...state, isLoggedIn: true, user: action.data, }; } case 'LOG_OUT': { return { ...state, isLoggedIn: false, user: null, }; } default: return state; } }; export default reducer; 터미널창 오류 메세지 입니다error - reducers/user.js (37:12) @ reducererror - ReferenceError: state is not defined at reducer (webpack-internal:///./reducers/user.js:39:13) at /Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:476:24 at Array.forEach (<anonymous>) at assertReducerShape (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:474:25) at combineReducers (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:539:5) at eval (webpack-internal:///./reducers/index.js:15:75) at Object../reducers/index.js (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/pages/_app.js:33:1) at __webpack_require__ (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/webpack-runtime.js:33:42) at eval (webpack-internal:///./store/configureStore.js:9:67) at Object../store/configureStore.js (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/pages/_app.js:66:1) { page: '/'} 35 | } 36 | default:> 37 | return state; | ^ 38 | 39 | } 40 | };event - compiled client and server successfully in 100 ms (1518 modules)4. WrappedApp created new store with withRedux(NodeBird) { initialState: undefined, initialStateFromGSPorGSSR: undefined }ReferenceError: state is not defined at reducer (webpack-internal:///./reducers/user.js:39:13) at /Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:476:24 at Array.forEach (<anonymous>) at assertReducerShape (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:474:25) at combineReducers (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/redux/lib/redux.js:539:5) at eval (webpack-internal:///./reducers/index.js:15:75) at Object../reducers/index.js (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/pages/_app.js:33:1) at __webpack_require__ (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/webpack-runtime.js:33:42) at eval (webpack-internal:///./store/configureStore.js:9:67) at Object../store/configureStore.js (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/.next/server/pages/_app.js:66:1) http://localhost:3060 에 뜬 오류 입니다 Server ErrorReferenceError: state is not definedThis error happened while generating the page. Any console logs will be displayed in the terminal window.Sourcereducers/user.js (35:12) @ reducer 33 | } 34 | default: > 35 | return state; | ^ 36 | 37 | } 38 | };
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
깃허브
PS C:\Users\user\Documents\boiler-plate> git push -u origin mainfatal: failed to load library 'libcurl-4.dll'이럴 경우엔 어떻게 깃허브 연결 할 수 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
ApolloError: null value in column "writer" of relation "board" violates not-null constraint
하드코딩으로 값을 넣었을때는 잘진행이 되었는데요ㅠㅠ 안에 값을 지정하니 에러가 계속뜨네요 아마 이 부분 에서 고쳐야 할 점이 있는 것 같은데 똑같이 작성을 한 것 같음에도 동작이 안되서 질문드려봅니다
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
윈도우 WSL 에서 yarn dev 후에 수정한 index.js 반영
브라우저에서 새로고침해도 수정된 index.js가 반영이 안되던데 왜그러는걸까요 ㅠ
-
해결됨처음 만난 리액트(React)
최종변환?
jsx강의 에서는 jsx는 내부적으로 html/xml코드를 자바스크립트로 변환하는 과정을 거치게 된다. 그래서 최종적으로는 자바스크립트 코드로 나오게 된다. 이렇게 말씀해주시고 jsx코드를 자바스크립트 코드로 변환하게 해주는 것이 react.createElement라고 하셨는데, 여기 강의 에서는 5분 35초 부근에 react.createElement 내부에 리액트 컴포넌트를 적어도 되고 모든 리액트 컴포넌트는 최종적으로는 html 태그를 사용하게 돼있다라고 하셨습니다. react.createElement를 통해서 최종적으로 자바스크립트가 된다는건가요? 아니면 html 코드가 된다는건가요,,?ㅠㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
과제가 노션에 있는 이미지인가요 영상에 나오는 이미지인가요?
이거 인가요? 피그마파일인가요? 둘중에 상관 없는거죠?