파이썬 예제 코드 실습 에러
미해결
퀀트 투자를 위한 주식 자동매매 봇 만들기 Part 1
예제 코드를 파이참을 실행해서 어느 프로그램 경로에다가 어떤식으로 연결해야 실행이 되는지 잘 모르겠습니다. 현재 예제 코드가 실행이 잘 안되서요
- python
- 투자
- 퀀트
172만명의 커뮤니티!! 함께 토론해봐요.
미해결
퀀트 투자를 위한 주식 자동매매 봇 만들기 Part 1
예제 코드를 파이참을 실행해서 어느 프로그램 경로에다가 어떤식으로 연결해야 실행이 되는지 잘 모르겠습니다. 현재 예제 코드가 실행이 잘 안되서요
해결됨
Slack 클론 코딩[실시간 채팅 with React]
만약 Page의 단위를 5로 잡아서 최초 랜더링한 페이지가 스크롤이 되지않는다면 onScroll 이벤트가 발생하지 않으니 setSize 이벤트도 발생할수 없습니다. 이렇게 최초 데이터의 개수가 모자라서 이벤트 자체가 발생하지 않으면 별개의 이벤트로 scroll이 가능할때까지 페이지를 불러와야 하는데 좋은 방법이 잇는가요? 페이지를 5개로 잡을떄 페이지를 20개로 잡을떄 참조 코드 import ChatBox from '@components/ChatBox'; import ChatList from '@components/ChatList'; import useInput from '@hooks/useInput'; import { Header, Container } from '@pages/DirectMessage/styles'; import fetcher from '@utils/fetcher'; import makeSection from '@utils/makeSection'; import axios from 'axios'; import gravatar from 'gravatar'; import React, { FC, FormEventHandler, useCallback, useEffect, useRef, useState } from 'react'; import Scrollbars from 'react-custom-scrollbars-2'; import { useParams } from 'react-router'; import useSWR from 'swr'; import useSWRInfinite from 'swr/infinite'; const PAGE_SIZE = 5; const DirectMessage: FC = () => { const { workspace, id } = useParams(); const { data: myData } = useSWR<IUser, false>('/api/users', fetcher); const { data: userData } = useSWR<IUser, false>(`/api/workspaces/${workspace}/users/${id}`, fetcher); const [chat, onChangeChat, setChat] = useInput(''); // const scrollbarRef = useRef(null); const { data: chatData, mutate: mutateChat, setSize, } = useSWRInfinite<IDM[]>( (index) => `/api/workspaces/${workspace}/dms/${id}/chats?perPage=${PAGE_SIZE}&page=${index + 1}`, fetcher, ); const isEmpty = chatData?.[0]?.length === 0; const isReachingEnd = isEmpty || (chatData && chatData[chatData.length - 1]?.length < PAGE_SIZE); const chatSection = makeSection(chatData ? [...chatData].flat().reverse() : []); const onSubmitForm = useCallback<FormEventHandler>( (event) => { event.preventDefault(); if (!chat || !chat?.trim()) { return; } axios .post(`/api/workspaces/${workspace}/dms/${id}/chats`, { content: chat, }) .then(() => { mutateChat(); setChat(''); }) .catch(console.error); console.log('제출'); }, [chat, id, mutateChat, setChat, workspace], ); const scrollbarRef = useRef<Scrollbars>(null); return !userData || !myData || !chatData ? null : ( <Container> <Header> <img src={gravatar.url(userData.email, { s: '24px', d: 'retro' })} alt={userData.nickname} /> <span>{userData.nickname}</span> </Header> <ChatList chatSections={chatSection} isEmpty={isEmpty} isReachingEnd={isReachingEnd} setSize={setSize} ref={scrollbarRef} /> <ChatBox onSubmitForm={onSubmitForm} chat={chat} onChangeChat={onChangeChat} placeholder={`Message ${userData.nickname}`} otherData={[userData]} /> </Container> ); }; export default DirectMessage; import Chat from '@components/Chat'; import { ChatZone, Section, StickyHeader } from '@components/ChatList/styles'; import React, { FC, MutableRefObject, forwardRef, useCallback } from 'react'; import { Scrollbars, positionValues } from 'react-custom-scrollbars-2'; interface Props { chatSections: { [key: string]: (IDM | IChat)[] }; isEmpty: boolean; isReachingEnd?: boolean; setSize: (f: (size: number) => number) => Promise<(IDM | IChat)[][] | undefined>; } const ChatList = forwardRef<Scrollbars, Props>(({ chatSections, isReachingEnd, isEmpty, setSize }, scrollRef) => { const onScroll = useCallback( (values: positionValues) => { if (values.scrollTop === 0 && !isReachingEnd) { setSize((size) => size + 1).then(() => { const current = (scrollRef as MutableRefObject<Scrollbars>)?.current; if (current) { current.scrollTop(current.getScrollHeight() - values.scrollHeight); } }); } }, [isReachingEnd, scrollRef, setSize], ); return ( <ChatZone> <Scrollbars autoHide ref={scrollRef} onScrollFrame={onScroll}> {Object.entries(chatSections).map(([dateData, chatData]) => ( <Section className={`section-${dateData}`} key={dateData}> <StickyHeader> <button>{dateData}</button> </StickyHeader> {chatData.map((chat) => ( <Chat key={chat.id} data={chat} /> ))} </Section> ))} </Scrollbars> </ChatZone> ); }); export default ChatList;
해결됨
Slack 클론 코딩[실시간 채팅 with React]
원본값을 유지하기위해 concat을 사용하셧는데 지금 같은 1차원 배열일때는 문제가 없지만 2차원 배열일 경우 해당 배열이 다쪼개져서 1차원 배열이 되는걸로 알고있습니다 그래서 저는 원본을 유지할때 스프레드 문법을 사용하는데 concat이 더 좋은경우도 있나요? 두가지 방법을 다 알려주시긴 하셧는데 차이점이 잇는가 궁금합니다. 예시상황 const chatData = [[1, 2], [3, 4], [5, 6]]; [].concat(...chatData).reverse() => [6, 5, 4, 3, 2, 1] [...chatData].reverse() => [[5, 6], [3, 4], [1, 2]]
해결됨
Slack 클론 코딩[실시간 채팅 with React]
기존 윈도우 스크롤바의 경우 스크롤바가 width를 잡아먹어 의도햇던 디자인이 찌그러 지는경우가 있어서 고민이엿습니다. 이번 강의에서 알려주신 react-custom-scrollbars 의경우 width를 잡아먹지 않고 내부에 생성되는걸로 확인되는데 vw,vh를 100%로 잡은 최상위 레이아웃을 만들고 react-custom-scrollbars 를 추가한뒤 그 자식으로 기존 코드들을 옮기려 합니다. 이때 문제가 될만한 이슈 또는 더 나은 방법이 잇을까요?
미해결
이런 식으로 코드를 사용중입니다 from PyQt6.QtWidgets import * from PyQt6.QtCore import * class thread (Qthread): def __init__(self): super().__init__() def run(self): while True: mainbot_window.fun1() class UI (QWidget): def __init__(self): super().__init__() self.inits() self.T1 = thread() self.T1.start() def inits(self): print("각종 변수 설정") def fun1(self): print("run code") def main(args=None): global mainbot_window app = QApplication(sys.argv) mainbot_window = UI() mainbot_window.show() try: app.exec() except KeyboardInterrupt: pass if __name__ == '__main__': main() 여기서 global 변수를 사용하지 않고 싶습니다. 글로벌 변수를 사용하지 않고 Thread 에서 Qwidget 의 함수를 사용할 방법이 있을까요? 시도한것 thread 에서 pyqtsignal.emit 을 사용해서 시도해봤는데 ui가 검은 화면으로 뜬체 작동하지않습니다. Qthread 대신 Qtimer 를 사용 =>작동은 잘되나 ui를 표시하는데 약간의 딜레이가 생깁니다. 그래서 되도록이면 Thread를 사용하고싶습니다.
해결됨
실전 프로젝트로 배우는 데이터 앱 만들기 with Python & Streamlit
안녕하세요 3강 콘다 가상환경에서 비주얼 스튜디오 터미널에서 conda activate myST해도 터미널에 계속 PS로 표시되며 가상환경으로 들어가지 않습니다. cmd에서는 같은 명령어를 입력하면 들어가지는데 비주얼 스튜디오 터미널에서는 들어가지지 않는 것 같습니다. 뭐가 문제일까요?
해결됨
Slack 클론 코딩[실시간 채팅 with React]
저는 평소에 아래와 같이 ComponentPropsWithoutRef을 이용하여 children이나 스타일등을 props로 내려받아 사용하고 있엇는데 export interface Props { /** 북마크 여부 */ isBookmark: boolean; /** 클릭했을 때 호출할 함수 */ onClick: (event: React.MouseEvent<HTMLButtonElement>) => void; } export const Bookmark = (Props: Props & ComponentPropsWithoutRef<"button">) => { return ( <ButtonStyle {...Props}> <BookmarkIcon isBookmark={Props.isBookmark} /> </ButtonStyle> ); }; export default Bookmark; 강의에서는 아래와같이 FC<PropsWithChildren<Props>> 형식으로 받아 오던데 둘이 어떤 차이가 있을까요? interface Props { show: boolean; onCloseModal: () => void; style: CSSProperties; closeButton?: boolean; } const Menu: FC<PropsWithChildren<Props>> = ({ closeButton, style, show, children, onCloseModal }) => { const stopPropagation = useCallback<MouseEventHandler<HTMLDivElement>>((event) => { event.stopPropagation(); }, []); if (!show) { return null; } return ( <CreateMenu onClick={onCloseModal}> <div onClick={stopPropagation} style={style}> {closeButton && <CloseModalButton onClick={onCloseModal}>×</CloseModalButton>} {children} </div> </CreateMenu> ); };
미해결
Slack 클론 코딩[실시간 채팅 with React]
슬랙 프로젝트의 환경설정(웹팩 등)을 토대로 새 프로젝트를 만들고 있습니다. 페이지 접속시 console.log를 찍어보니 3번 찍히는 문제가 있습니다. 원인 및 해결방법을 모르겠어서 질문드립니다. 아래는 라우터 쪽입니다. login과 signup은 loadble을 사용해서 그런지 1번만 console.log가 찍혔습니다. 아래 stockrecode에 해당하는 페이지가 3번 console.log 찍힙니다. 아래는 stockrecode 컴포넌트에 있는 코드입니다. 나머지는 다 주석처리하였습니다. 아래는 로 이동시에 표시된 내용입니다. useSwr 사용 부분을 지우면 2번 표시됩니다. <해본 방법> strict-mode를 지우면 되는 글을 보아서 찾아봤는데 이미 strict-mode가 없는 상태였습니다. 2.웹팩에서 strict-mode를 false로 하면 되는 글을 보고 해보았는데 (관련 링크 https://www.sobyte.net/post/2021-09/webpack-strip-use-strict/) 아래처럼 @babel/plugin-transform-modules-commonjs 설치를 하고 적용해보았는데도 아래처럼 에러가 생겨서 이 방법으로도 해결하지 못하였습니다 답변주시는데 더 필요한 정보가 있으시면 말씀부탁드립니다. 꼭 해결하고 싶은데 제자리만 멤도는거 같아 질문 올립니다. ㅠ
미해결
Do it! 알고리즘 코딩테스트 with Python
올려주신 코드로 공부하고 백준에 업로드 해 본 결과 시간 초과가 뜨는데, 시간 초과가 되지 않게 하려면 어떻게 수정할 수 있을까요 ?
해결됨
Slack 클론 코딩[실시간 채팅 with React]
안녕하세요 질문드립니다! 아직 초반이지만 언젠가부터 cors 에러가 계속 나고 있는데 baseURL 도 아래와 같이 변경했습니다. axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? 'http://localhost:3095' : 'http://localhost:3090'; 제 코드엔 nodebird 라는 글자 자체가 없는데 어디가 잘못된 건가요......
미해결
실리콘밸리 엔지니어가 가르치는 파이썬 기초부터 고급까지
128줄에 return inside에서 inside()를 안하는 이유가 궁금합니다 @higher_order_example 자체가 inside 리턴받은 함수를 자동으로 ()붙여서 실행해주는 것인가요? 136줄에 sample_example()을 안쓰면 121줄에 있는 func 매개변수로 못넣는것인가요???
미해결
Slack 클론 코딩[실시간 채팅 with React]
안녕하세요 질문 드립니다. npm 설치할 때 이러 경고가 나타났는데, 에러는 아니길래 그냥 지나갔는데, 로컬호스트3095 들어가면 계속 이러 에러가 나와서 진행이 안 되고 있어요 서버는 잘 연결되었습니다
미해결
Slack 클론 코딩[실시간 채팅 with React]
안녕하세요! 강의 정말 잘 듣고 있습니다. 저에게 여러모로 큰 도움이 되고 있는 것 같습니다! 다른게 아니라 강의를 들으면서 아직 웹소켓에 대해 잘 몰라서 정확한 로직을 잘 모르겠어서 질문을 드립니다! 소켓을 사용하는 로직이 한 클라이언트에 대해 워크스페이스를 바꿀 때 마다 해당 워크스페이스에 대한 소켓을 연결 서버는 워크스페이스 별로 소켓을 관리. 채널과 디엠 상관없이 워크스페이스 별로 들어오는 모든 소켓 요청(채팅 내용)을 받아서 전달함 클라이언트는 해당 채팅 내용들을 다 받지만 현재 접속해있는 채널이나 dm을 주고 받는 상대에 대한 채팅 내용만 걸러서 화면에 보여줌 이렇게 진행되는 것이 맞을까요? 맞다면 혹시 워크스페이스라는 개념이 없이 채팅방만 있거나 1:1 채팅의 기능만 소켓을 사용하여 구현한다고 했을 때는 채팅방 별로 혹은 클라이언트 별로 소켓을 생성해서 구현을 하게 되나요..? 그게 아니라면 보통 어떻게 구현하는지 질문 드리고 싶습니다..! 감사합니다
미해결
[개정판] 파이썬 머신러닝 완벽 가이드
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 강의 내용을 질문할 경우 몇분 몇초의 내용에 대한 것인지 반드시 기재 부탁드립니다. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 선생님 보스턴 가격예측 데이터 임포트가 안돼요 ㅠㅠ
미해결
[신규 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)
안녕하세요. 강사님 아래 코드에서 '블랙핑크' 를 검색할 때 Traceback (most recent call last): File "c:\pratice_crolling\심화1_\03_스포츠 뉴스 크롤링.py ", line 52, in <module> print(article_title.text.strip()) ^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'text' 다음과 같은 오류가 뜹니다 ㅠㅠ CSS 선택자, 오타도 모두 맞게 확인이 되는데 왜 저 검색어만 오류가 뜰까요ㅠㅠ? # -*- coding: euc-kr -*- # 네이버에서 손흥민, 오승환과 같은 스포츠 관련 검색어 크롤링하기 import requests from bs4 import BeautifulSoup import pyautogui import time search = pyautogui.prompt("어떤 것을 검색하시겠어요?") response = requests.get(f"https://search.naver.com/search.naver?sm=tab_hty.top&where=news&query={search}&oquery=%EC%98%B7%EC%9C%BC%ED%99%98&tqi=i74G%2FdprvTossZPeMhCssssssko-058644") html = response.text soup = BeautifulSoup(html, "html.parser") articles = soup.select(".info_group") for article in articles: # '네이버뉴스' 가 있는 기사만 추출한다. (<a> 하이퍼링크가 2개 이상인 경우에 해당) links = article.select("a.info") if len(links) >=2 : url = links[1].attrs['href'] response = requests.get(url, headers={'User-agent':'Mozila/5.0'}) html = response.text soup = BeautifulSoup(html, "html.parser") # 스포츠 기사인 경우 if "sports" in url: article_title = soup.select_one("h4.title") article_body = soup.select_one("#newsEndContents") # 본문 내에 불필요한 내용 제거 p태그와 div태그의 내용은 출력할 필요가 없다. 없애주자. p_tags = article_body.select("p") # 본문에서 p 태그인 것들을 추출 for p_tag in p_tags: p_tag.decompose() div_tags = article_body.select("div") # 본문에서 div 태그인 것들을 추출 for div_tag in div_tags: div_tag.decompose() # 연예 기사인 경우 elif "entertain" in url: article_title = soup.select_one(".end_tit") article_body = soup.select_one("#articeBody") # 일반 뉴스 기사인 경우 else: article_title = soup.select_one("#title_area") article_body = soup.select_one("#dic_area") # 출력문 print("==================================================== 주소 ===========================================================") print(url.strip()) print("==================================================== 제목 ===========================================================") print(article_title.text.strip()) print("==================================================== 본문 ===========================================================") print(article_body.text.strip()) #strip 함수는 앞 뒤의 공백을 제거한다. time.sleep(0.3)
미해결
Slack 클론 코딩[실시간 채팅 with React]
안녕하세요 제로초님. 강의 잘 듣고 있습니다. 다름이 아니라 채널 토글에서 각 채널을 선택하면 정상적으로 이동하지만, DMlist에서 선택하면 아래와 같이 useEffect가 무한루프처럼 호출되어 문제가 발생하는 것 같습니다. 제로초님께서 업로드해주신 코드와 동일하게 def에 workspace를 넣어 작성했는데, 어떠한 부분에서 위와 같이 무한로딩되는 에러가 발생하는지 못 찾겠습니다ㅠㅠ DMList/index.tsx // import useSocket from '@hooks/useSocket'; import { CollapseButton } from '@components/DMList/style'; import { IDM, IUser, IUserWithOnline } from '@typings/db'; import fetcher from '@utils/fetcher'; import React, { FC, useCallback, useEffect, useState } from 'react'; import { useParams } from 'react-router'; import { NavLink } from 'react-router-dom'; import useSWR from 'swr'; const DMList: FC = () => { const { workspace } = useParams<{ workspace?: string }>(); const { data: userData, error, 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[]>([]); const toggleChannelCollapse = useCallback(() => { setChannelCollapse((prev) => !prev); }, []); const resetCount = useCallback( (id) => () => { setCountList((list) => { return{ ...list, [id]: 0, }; }); }, [], ); const onMessage = (data: IDM) => { console.log("DM 왓따", data); setCountList((list) => { return { ...list, [data.SenderId] : list[data.SenderId] ? list[data.SenderId]+1 : 1, }; }); }; useEffect(() => { console.log('DMList: workspace 바꼈다', workspace); setOnlineList([]); setCountList({}); }, [workspace]); // useEffect(() => { // socket?.on('onlineList', (data: number[]) => { // setOnlineList(data); // }); // socket?.on('dm', onMessage); // console.log('socket on dm', socket?.hasListeners('dm'), socket); // return () => { // socket?.off('dm', onMessage); // console.log('socket off dm', socket?.hasListeners('dm')); // socket?.off('onlineList'); // }; // }, [socket]); return ( <> <h2> <CollapseButton collapse={channelCollapse} onClick={toggleChannelCollapse}> <i className="c-icon p-channel_sidebar__section_heading_expand c-icon--caret-right c-icon--inherit c-icon--inline" data-qa="channel-section-collapse" aria-hidden="true" /> </CollapseButton> <span>Direct Messages</span> </h2> <div> {!channelCollapse && memberData?.map((member) => { const isOnline = onlineList.includes(member.id); return ( <NavLink key={member.id} activeClassName="selected" to={`/workspace/${workspace}/dm/${member.id}`} > <i className={`c-icon p-channel_sidebar__presence_icon p-channel_sidebar__presence_icon--dim_enabled p-channel_sidebar__presence_icon--on-avatar c-presence ${ isOnline ? 'c-presence--active c-icon--presence-online' : 'c-icon--presence-offline' }`} aria-hidden="true" data-qa="presence_indicator" data-qa-presence-self="false" data-qa-presence-active="false" data-qa-presence-dnd="false" /> <span>{member.nickname}</span> {member.id === userData?.id && <span> (나)</span>} </NavLink> ); })} </div> </> ); }; export default DMList;
해결됨
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) 이런 에러가 나오는데, 이건 서버 접속이 아예 안되었기 때문에 나오는 거겠죠..?
미해결
Slack 클론 코딩[실시간 채팅 with React]
안녕하세요. 강의 잘 듣고 있습니다. 다름이 아니라 login 한 후 workspace로 리다이렉트 된 후, workspace 목록이 아래와 같이 나타나지 않는 현상이 발생합니다. 하지만 다른 탭을 다녀오거나, workspace 추가를 하면 다시 정상적으로 아래와 같이 workspace 목록이 나타납니다. 아마 userData를 리다이렉트하면서 불러오지 않아 생기는 문제 같습니다. mutate()를 사용하고, dedupinginterval을 줄여도 문제 해결이 안되는 것 같아 리다이렉트됨과 동시에 다시 userData를 불러오도록 수정해야 할 것 같은데, 이를 구현할 수 있는 방법이 생각이 나지 않습니다. 현재 제 코드 일부 아래에 첨부합니다. App.js const 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.tsx const 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.tsx import 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
미해결
Slack 클론 코딩[실시간 채팅 with React]
react를 처음 접해보는 취준생입니다. 제가 강의를 보면서 따라하려는데 settings/js 디렉토리의 디렉토리명을 front로 변경해서 사용하고 back 디렉토리에서 npm start로 백앤드 서버 실행시키고 따라하라고 하신거 같아서 그렇게 따라하고 있습니다. 현재 localhost :3095로 접근하면 슬리액 페이지가 잘 나오는데 front 디렉토리에서 코드 수정해도 반영이 안고 있는데 혹시 어떤걸 잘 못 하고 있는지 알 수 있을까요?
해결됨
Python 알고리즘 베스트 10
안녕하세요 PDF파일은 출력하려고 하는데, 노션을 보면 "PDF 노션 페이지에서 다운로드하실 수 있습니다." 로만 되어있는데 다운받을 수 있는 링크는 어디에 있나요? 노션에서 전체PDF출력하려면 비지니스라서 불가능한데... 확인부탁드립니다.