39,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결Slack 클론 코딩[실시간 채팅 with React]
구현 없이 빈 껍데기만 있는 파일은 어디서 보나요?
예를들어 4분 46초에 보면 useState등 선언만 되어있는 코드들이 있는데, 이런 초기 파일은 어디서 구할 수 있나요?
- 미해결Slack 클론 코딩[실시간 채팅 with React]
코드스플리팅과 이모션
1. C:\Users\sam77\Downloads\sleact-master\alecture>npm run dev > alecture@1.0.0 dev > cross-env TS_NODE_PROJECT="tsconfig-for-webpack-config.json" webpack serve --env development [webpack-cli] Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options has an unknown property 'publicPath'. These properties are valid: object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, server?, setupExitSignals?, setupMiddlewares?, static?, watchFiles?, webSocketServer? } 2. C:\Users\sam77\Downloads\sleact-master\alecture>npm i emotion/react info: please complete authentication in your browser...eaning logs, removing 2 files npm ERR! code 128 om/emotion/react.git npm ERR! git@github.com: Permission denied (publickey). om/emotion/react.git npm ERR! fatal: Could not read from remote repository. npm ERR! npm ERR! Please make sure you have the correct access rights npm ERR! and the repository exists. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\sam77\AppData\Local\npm-cache\_logs\2022-03-05T07_20_43_694Z-debug-0.log 7_20_43_694Z-debug-0.log 이런식으로 에러가 뜨는데 그냥 진행해도 되나요? 3. C:\Users\sam77\Downloads\sleact-master\alecture>npm start npm ERR! Missing script: "start" npm ERR! npm ERR! Did you mean one of these? npm ERR! npm star # Mark your favorite packages npm ERR! npm stars # View packages marked as favorites npm ERR! npm ERR! To see a list of scripts, run: npm ERR! npm run npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\sam77\AppData\Local\npm-cache\_logs\2022-03-05T07_39_21_665Z-debug-0.log npm start를 했을때 안되는 이유도 궁금합니다
- 미해결Slack 클론 코딩[실시간 채팅 with React]
optimistic ui 구현중 질문이 있습니다
안녕하세요 강사님 현재 강사님의 강의를 따라 실습하며 공부해가고 있는데 한가지 궁금한 점이 있어 질문을 올리게 되었습니다 optimistic ui 구현하실때 더미데이터? 로 createdAt에 new Date를 넣으셨는데 그러면 axios로 서버에 요청할때랑 시간이 달지는게 아닌가요? 그래서 서버요청이 끝나고 똑같은 채팅이 두개가 보여지지 않을까 했는데 하나로만 나오더라구요 제생각에는 아주 조금이라도 차이가 있을줄 알았는데 간략한 원리를 설명해 주실 수 있을까요
- 미해결Slack 클론 코딩[실시간 채팅 with React]
npx sequelize db:create 입력시 에러
npx sequelize db:create Sequelize CLI [Node: 16.14.0, CLI: 6.4.1, ORM: 6.17.0] ERROR: Error reading "config/config.js". Error: Error: Cannot find module 'dotenv' Require stack: - /Users/iju-i/Desktop/sleact/back/config/config.js 이런 에러가 뜨는데 어떻게 해야할까요?ㅠㅠ
- 미해결Slack 클론 코딩[실시간 채팅 with React]
() => void가 어떤 뜻인가요?
궁금합니다!!
- 미해결Slack 클론 코딩[실시간 채팅 with React]
설정..
1. 이렇게 뜨면 eslint랑 prettier가 제대로 설치된건가요..? C:\Users\sam77\Downloads\sleact-master\alecture>npm i -D eslint up to date, audited 1036 packages in 4s 81 packages are looking for funding run `npm fund` for details 26 vulnerabilities (2 low, 12 moderate, 10 high, 2 critical) To address issues that do not require attention, run: npm audit fix To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. C:\Users\sam77\Downloads\sleact-master\alecture>npm i -D prettier up to date, audited 1036 packages in 3s 81 packages are looking for funding run `npm fund` for details 26 vulnerabilities (2 low, 12 moderate, 10 high, 2 critical) To address issues that do not require attention, run: npm audit fix To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. C:\Users\sam77\Downloads\sleact-master\alecture>npm i -D eslint-config-prettier eslint-plugin-prettier up to date, audited 1036 packages in 3s 81 packages are looking for funding run `npm fund` for details 26 vulnerabilities (2 low, 12 moderate, 10 high, 2 critical) 2. 강의에는 모듈 라이브러리 루트가 있는데 저한텐 없어서, 제가 직접 만들어야하나요? 힘들다ㅠㅠㅠ
- 미해결Slack 클론 코딩[실시간 채팅 with React]
1강 sql비번 에러
패스워드가 no라니... 사용자 이름은 root가 맞는데 왜 안돌까요..
- 미해결Slack 클론 코딩[실시간 채팅 with React]
eslint 5개 강의에서 설명해주신 부분
설치하고 eslintrc에 react-app을 추가했는데도 eslint가 활성화가 안되는데, vscode 오류일까요?
- 미해결Slack 클론 코딩[실시간 채팅 with React]
Section으로 묶여있는데 react-virtulized와 같은 가상화 라이브러리를 적용할 수 있을까요??
최근 타 프로젝트에서 무한스크롤과 렌더링 성능 이슈를 해결하면서 React.memo와 react-virtualized, react-window 등의 방법을 찾아서 해결했었는데 그 때의 상황은 노드버드와 같이 같은 컴포넌트를 무한으로 렌더하는 상황이였습니다. 해결은 react-virtualized를 이용했었습니다. 이번 슬리액트강좌에도 무한스크롤이 있길래 잘 보니 날짜별로 묶어 표시하는 기능이 구현되어 있던데 어떻게 해야 적용이 될 지 감이 잘 안잡히네요. 뷰포트의 날짜 데이터를 감지해서 화면에 강제로 뿌리는 억지?스러운 방법 밖에 생각나지 않는데단순히 같은 컴포넌트의 데이터를 렌더링 하는게 아니라 날짜별 섹션으로 묶어 표시하려고 하면react-virtulized나 react-window는 적합하지 않은 라이브러리 선택일지,깔끔한 방법이 있는데 제가 생각을 못하는 것인지 의견이 궁금해서 질문으로 남깁니다! 추가로 모바일이나 태블릿에서 사용 시 innerScroll이라고 해야하나, 화면 전체의 windowScroll?이 아닌 경우 상단을 터치하여 최상단으로 스크롤하는 기능이 먹지 않던데 엘리먼트의 스크롤을 화면 전체의 스크롤로 연동시키는 등의 방법으로 해결하신 경험이 있으시면 관련 내용도 슬쩍 공유해주시면 감사하겠습니다.,.
- 해결됨Slack 클론 코딩[실시간 채팅 with React]
show props 만드신이유가 궁금합니다!
안녕하세요 제로초님 showUserMenu state를 show로 넘기셨는데 Menu 컴포넌트에서는 왜 show를 사용하지 않으시는지 궁금합니다!
- 미해결Slack 클론 코딩[실시간 채팅 with React]
useInput not fount 에러
자꾸 module not fount 'useInput' 에러가 발생합니다. useInput은 export와 import가 모두 잘 이루어졌고 IDE 상에서는 어떠한 오류도 발생하지 않고 useInput을 import하여 사용할 수 있었습니다만 npm run dev를 실행하면 자꾸 에러가 발생합니다..
- 해결됨Slack 클론 코딩[실시간 채팅 with React]
channel 라우터가 기본적으로 적용되는 이유?
안녕하세요! 라우터에 채널이랑 DM적용하셨는데 왜 그중 채널라우터가 기본적으로 실행되는지 궁금합니다!
- 미해결Slack 클론 코딩[실시간 채팅 with React]
채널 생성시 404오류
안녕하세요!!! 강좌 열심히 따라하면서 배우는 중, 해결점을 찾을수 없는 부분이 있어서 질문합니다. *우선 리액트 v6를 사용하여 route가 아래와 같이 되었다는 것을 참고해주세요. **SWR역시 revalidate가 작동이 안되어, mutate사용하였습니다. [이슈사항] 채널 리스트는 잘 받아오는 것 같습니다. 하지만, 채널생성시 404에러가 발생합니다. 서버는 "존재하지 않는 워크스페이스입니다."라는 응답을 줍니다. 의심되는 것은 버전6 라우팅설정에 문제가 있지 않을까 생각되는데... 검색해봐도 딱히 잘못된것을 못 발견해서 이렇게 질문남깁니다. //CreateChannelModal 코드 import Modal from '@components/Modal';import React, { CSSProperties, useCallback, VFC } from 'react';import { Button, Input, Label } from '@pages/SignUp/styles';import useInput from '@hooks/useinput';import axios from 'axios';import { useParams } from 'react-router';import { toast } from 'react-toastify';import useSWR from 'swr';import { IChannel, IUser } from '@typings/db';import fetcher from '@utils/fetcher';interface Props { show: boolean; onCloseModal: () => void; setShowCreateChannelModal: (flag: boolean) => void;}const CreateChannelModal: VFC<Props> = ({ show, onCloseModal, setShowCreateChannelModal }) => { const [newChannel, onChangeNewChannel, setNewChannel] = useInput(''); const { workspace, channel } = useParams<{ workspace: string; channel: string }>(); const { data: userData, error, mutate } = useSWR<IUser | false>('http://localhost:3095/api/users', fetcher); const { data: channelData, mutate: mutateChannel } = useSWR<IChannel[]>( // 로그인하지 않은상태이면 호출안하고, null로 userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null, fetcher, ); const onCreateChannel = useCallback( (e) => { e.preventDefault(); axios .post( 'http://localhost:3095/api/workspaces/${workspace}/channels', { name: newChannel, }, { withCredentials: true, }, ) .then(() => { setShowCreateChannelModal(false); mutateChannel(); setNewChannel(''); }) .catch((error) => { console.dir(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [newChannel], ); return ( <Modal show={show} onCloseModal={onCloseModal}> <form onSubmit={onCreateChannel}> <Label id="channel-label"> <span>채널 이름</span> <Input id="channel" value={newChannel} onChange={onChangeNewChannel} /> </Label> <Button type="submit">생성하기</Button> </form> </Modal> );};export default CreateChannelModal; //Workspace 코드import React, { VFC, useCallback, useState } from 'react';import useSWR, { mutate } from 'swr';import fetcher from '@utils/fetcher';import axios from 'axios';import { Routes, Route, Navigate, Link } from 'react-router-dom';import { Header, LogOutButton, ProfileImg, ProfileModal, RightMenu, WorkspaceWrapper, Workspaces, Channels, Chats, WorkspaceName, MenuScroll, WorkspaceButton, AddButton, WorkspaceModal,} from '@layouts/Workspace/styles';import gravatar from 'gravatar';import loadable from '@loadable/component';import Menu from '@components/Menu';import { IChannel, IUser } from '@typings/db';import { Button, Input, Label } from '@pages/SignUp/styles';import useInput from '@hooks/useinput';import Modal from '@components/Modal';import CreateChannelModal from '@components/CreateChannelModal';import { toast } from 'react-toastify';import { useParams } from 'react-router';const Channel = loadable(() => import('@pages/Channel'));const DirectMessage = loadable(() => import('@pages/DirectMessage'));const Workspace: VFC = () => { 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>('http://localhost:3095/api/users', fetcher); const { data: channelData } = useSWR<IChannel[]>( // 로그인하지 않은상태이면 호출안하고, null로 userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null, fetcher, ); const onLogout = useCallback((e) => { e.preventDefault(); axios .post('http://localhost:3095/api/users/logout', null, { withCredentials: true, }) .then((response) => { mutate(false, false); }); }, []); const onCloseUserProfile = useCallback((e) => { e.stopPropagation(); setShowUserMenu(false); }, []); const onClickUserProfile = useCallback(() => { 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( 'http://localhost:3095/api/workspaces', { workspace: newWorkspace, url: newUrl, }, { withCredentials: true, }, ) .then((response) => { mutate(response.data); 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); }, []); const toggleWorkspaceModal = useCallback(() => { setShowWorkspaceModal((prev) => !prev); }, []); const onClickAddChannel = useCallback(() => { setShowCreateChannelModal(true); }, []); if (!userData) { return <Navigate replace to="/login" />; } return ( <div> <Header> <RightMenu> <span onClick={onClickUserProfile}> <ProfileImg src={gravatar.url(userData.email, { s: '28px', d: 'retro' })} alt={userData.email} /> {showUserMenu && ( <Menu style={{ right: 0, top: 38 }} show={showUserMenu} onCloseModal={onCloseUserProfile}> <ProfileModal> <img src={gravatar.url(userData.email, { s: '36px', d: 'retro' })} alt={userData.email} /> <div> <span id="profile-name">{userData.email}</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> {/*<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={onClickInviteWorkspace}>워크스페이스에 사용자 초대</button>*/} <button onClick={onClickAddChannel}>채널 만들기</button> <button onClick={onLogout}>로그아웃</button> </WorkspaceModal> </Menu> {channelData?.map((v) => ( <div>{v.name}</div> ))} </MenuScroll> </Channels> <Chats> chats <Routes> <Route path="/channel/:channel" element={<Channel />} /> <Route path="/dm/:id" element={<DirectMessage />} /> </Routes> </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" value={newUrl} onChange={onChangeNewUrl} /> </Label> <Button type="submit">생성하기</Button> </form> </Modal> <CreateChannelModal show={showCreateChannelModal} onCloseModal={onCloseModal} setShowCreateChannelModal={setShowCreateChannelModal} /> </div> );};export default Workspace; //App코드입니다import React from 'react';import loadable from '@loadable/component';import { Routes, Route, Navigate } from 'react-router-dom';const LogIn = loadable(() => import('@pages/LogIn'));const SignUp = loadable(() => import('@pages/SignUp'));const Workspace = loadable(() => import('@layouts/Workspace'));const App = () => { return ( <Routes> <Route path="/" element={<LogIn />} /> <Route path="/login" element={<LogIn />} /> <Route path="/signup" element={<SignUp />} /> <Route path="/workspace/:workspace/*" element={<Workspace />} /> </Routes> );};export default App;
- 미해결Slack 클론 코딩[실시간 채팅 with React]
실제 배포시에는 webpack dev server의 historyApiFallback 설정 같은 건 어떻게 하나요?
제로초님 안녕하세요. 강의 중에 webpack dev server에서 historyApiFallback 설정을 통해서 리액트 앱에서 새로고침을 했을 때 react router에 의해서 부여된 url로 바로 접근하더라도 프론트엔드에서 바로 처리하게끔 할 수 있다는 식으로 이해했는데요. 혹시 실제로 배포시에는 어떤 식으로 처리할 수 있나요? 서버단에서 index.html 외에 다른 html 파일을 보내주도록 하는 것도 방법일 것 같은데 별로 좋지 않은 방법 같다는 생각이 들었고요. 리액트단에서 할 수 있는 일이 있을 것 같은데 어떻게 하면 될지 감이 잘 오지 않네요. 코드 없이 여쭤보는 질문이다보니 혹시 어떤 식으로 가능할지 대략적으로 큰 그림만 좀 알려주실 수 있을까요? 좋은 강의 감사합니다.
- 미해결Slack 클론 코딩[실시간 채팅 with React]
header에서 a태그 들어간 후 해당 접속 중인 페이지 header a태그 색 바꾸기
안녕하세요 제로초님 제가 Header 에 있는 a태그들을 지금 들어가 있는 페이지이라면? 해당 a태그를 검정색으로 지정 해 주고 싶습니다. 제가 스타일컴포넌트를 이용하고 삼항 연산자를 이용 해 적용 했는데 반응 하지 않습니다. 왜 그럴까요 ㅠㅠ. const Header = () => { const location = useLocation(); const SLink = styled(Link)` color: ${location.pathname ? "#4e5968" : "#000000"}; cursor: pointer; ` console.log(location.pathname); // 순서 a링크 클릭 -> /order return ( <> <Headers> <div> <h1>제로초짱</h1> <Ul> <li> <SLink to="/order">순서</SLink> </li> <li> <SLink to="/">메인 페이지</SLink> </li> <li> <SLink to="/rotationservice">환불</SLink> </li> </Ul> </div> </Headers> </> ); }; export default Header;
- 미해결Slack 클론 코딩[실시간 채팅 with React]
DMList 소켓 연결 중에 타입스크립트 에러
const DMList: FC = () => { const { workspace } = useParams<{ workspace?: string }>(); const { data: userData, error, revalidate, mutate, } = useSWR<IUser>("/api/users", fetcher, { dedupingInterval: 2000, // 2초 }); const { data: memberData } = useSWR<IUserWithOnline[]>( userData ? `/api/workspaces/${workspace}/members` : null, fetcher ); const [socket] = useSocket(workspace); const [channelCollapse, setChannelCollapse] = useState(false); const [countList, setCountList] = useState<{ [key: string]: number }>({}); const [onlineList, setOnlineList] = useState<number[]>([]); useSocket(workspace)에서 TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'. 에러가 뜨는데 workspace?: string으로 명시해주었는데 왜 이런 에러가 발생하는건가요? 깃허브에서 똑같이 코드를 가져왔는데도 같은 에러가 발생해서 어떤 점이 문제인지 도무지 알 수가 없어 여쭈어봅니다..ㅠㅠㅠ
- 미해결Slack 클론 코딩[실시간 채팅 with React]
swr 질문
안녕하세요 제로초님 좋은 강의 잘 듣고 있습니다! 질문이 있는데요 로그인 성공 시 서버로부터 받은 세션으로 사용자 정보를 swr로 받고 싶습니다. 여기서 질문이 있습니다 1. LogIn 컴포넌트에서 로그인을 성공하게 되면 revalidated가 불리면서 세션에 사용자 정보가 저장되는게 맞나요? 2. 제가 현재 구현하고 있는 서버가 Spring Boot + Spring Security 인데 다중 사용자이므로 email을 req param으로 전달하고 정보를 리턴받습니다. 이럴 경우에 workspace 레이아웃에서는 email 정보로 swr 요청 하는 방법을 .. 모르겠습니다ㅠ 3. 1번의 질문이 참이라면 세션의 사용자 정보를 가져다가 2번의 param으로 사용하여 swr 요청할 수 있을거 같은데 가능할까요..? 답변 주시면 감사하겠습니다!
- 미해결Slack 클론 코딩[실시간 채팅 with React]
npm run dev 오류
npm run build 실행시 버전 오류가 발생하는 것 같습니다.
- 미해결Slack 클론 코딩[실시간 채팅 with React]
리액트 빌드 오류
npm run build를 실행하니 위와 같이 js파일 뿐만 아니라 js.map파일도 생성됩니다. 그리고 node_modules관련 js파일은 빌드되지 않은 거 같은데 webpack설정에서 문제가 있는걸까요? 그리고 html파일을 실행시키면 <script src="/dist/app.js"></script> 이 상태일 때는 경로를 못찾아서 앞에 .을 붙여주면 경로를 찾기는 하는데 이런 오류들이 뜹니다...
- 미해결Slack 클론 코딩[실시간 채팅 with React]
인피니티 스크롤 시 데이터 일부를 가져오지 못하는 문제
채팅방에서 새로운 데이터를 입력한 후, 스크롤을 위로 올려 다음 페이지를 로드하면 다음 페이지 값의 일부가 사라져서 출력되는 것 같습니다. 사진에서 5를 새로 입력했습니다. 그리고 나서 위에 닿을 때까지 천천히 스크롤하여 새로운 페이지를 불러오면 8 다음에 있어야 할 9를 불러오지 못했습니다. 테스트는 강좌 깃헙의 front 폴더와 back 폴더에 있는 코드로 진행 했습니다. 버그인 것인지, 페이지를 불러오는 과정에서 문제가 생긴건지 궁금합니다ㅠㅠ..