묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
logoutUser 질문입니다
이렇게 떠서 구글링, 유튜브를 보는데 안나와가지고 혹시 방법을 여쭤봐도 될까요 ㅠ
-
미해결Slack 클론 코딩[실시간 채팅 with React]
사용자 초대 모달에서 에러가 발생했습니다.
import fetcher from '@utils/fetcher'; import axios from 'axios'; import React, { VFC, useCallback, useState } from 'react'; import { Redirect, Route, Switch, useParams } from 'react-router'; import useSWR from 'swr'; import { Header, ProfileImg, RightMenu, WorkspaceWrapper, WorkspaceName, Workspaces, Channels, Chats, MenuScroll, ProfileModal, LogOutButton, WorkspaceButton, AddButton, WorkspaceModal, } from './styles'; import gravatar from 'gravatar'; import loadable from '@loadable/component'; import Menu from '@components/Menu'; const Channel = loadable(() => import('@pages/Channel')); const DirectMessage = loadable(() => import('@pages/DirectMessage')); import { Link } from 'react-router-dom'; import { IChannel, IUser } from '@typings/db'; import Modal from '@components/Modal'; import { Button, Input, Label } from '@pages/SignUp/styles'; import useInput from '@hooks/useInput'; import { toast } from 'react-toastify'; import CreateChannelModal from '@components/CreateChannelModal'; import InviteWorkspaceModal from '@components/InviteWorkspaceModal'; import InviteChannelModal from '@components/InviteChannelModal'; // import ChannelList from '@components/ChannelList'; import DMList from '@components/DMList'; import ChannelList from '@components/ChannelList'; // FC타입안에 children이 알아서 들어있음 // children 안쓸거면 VFC const Workspace: VFC = () => { const [showUserMenu, setShowUserMenu] = useState(false); const [showCreateWorkspaceModal, setShowCreateWorkspaceModal] = useState(false); const [showInviteWorkspaceModal, setShowInviteWorkspaceModal] = useState(false); const [showInviteChannelModal, setShowInviteChannelModal] = useState(false); const [newWorkspace, onChangeNewWorkspace, setNewWorkspace] = useInput(''); const [newUrl, onChangeNewUrl, setNewUrl] = useInput(''); const [showWorkspaceModal, setShowWorkspaceModal] = useState(false); const [ShowCreateChannelModal, setShowCreateChannelModal] = useState(false); const { workspace } = useParams<{ workspace: string }>(); // 사용자 데이터 가져오기 const { data: userData, error, revalidate, mutate, } = useSWR<IUser | false>('/api/users', fetcher, { dedupingInterval: 2000, }); // channel 데이터 가져오기 const { data: channelData } = useSWR<IChannel[]>(userData ? `/api/workspaces/${workspace}/channels` : null, fetcher); // 워크스페이스에 있는 멤버 데이터 const { mutate: revalidateMembers } = useSWR<IUser[]>( userData ? `/api/workspaces/${workspace}/members` : null, fetcher, ); // 로그아웃 const onLogout = useCallback(() => { axios .post('/api/users/logout', null, { withCredentials: true, }) .then((response) => { mutate(response.data); // 기존에 받은 데이터를 mutate의 data에 담음 }) .catch((error) => { console.log(error); }); }, []); // 프로필 누르면 메뉴 보이기 const onClickUserProfile = useCallback(() => { setShowUserMenu((prev) => !prev); }, []); // 프로필 닫기 const onCloseUserProfile = useCallback((e) => { e.stopPropagation(); setShowUserMenu(false); }, []); // 워크스페이스 모달 열기 const onClickCreateWorkspace = useCallback(() => { setShowCreateWorkspaceModal(true); }, []); // 워크스페이스 모달 닫기 const onCloseModal = useCallback(() => { setShowCreateWorkspaceModal(false); setShowCreateChannelModal(false); setShowInviteChannelModal(false); setShowInviteWorkspaceModal(false); }, []); // 워크스페이스 생성 const onCreateWorkspace = useCallback( (e) => { e.preventDefault(); // trim() 안넣으면 띄어쓰기 넣으면 걍 통과됨 if (!newWorkspace || !newWorkspace.trim()) return; if (!newUrl || !newUrl.trim()) return; axios .post( '/api/workspaces', { workspace: newWorkspace, url: newUrl, }, { withCredentials: true, }, ) .then(() => { revalidate(); setShowCreateWorkspaceModal(false); setNewWorkspace(''); setNewUrl(''); }) .catch((error) => { console.log(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [newWorkspace, newUrl], ); // 워크스페이스 사용자 초대 const onClickInviteWorkspace = useCallback(() => { setShowInviteWorkspaceModal(true); }, []); // Channel // 토글 const toggleWorkspaceModal = useCallback(() => { setShowWorkspaceModal((prev) => !prev); }, []); // 채널 만들기 const onClickAddChannel = useCallback(() => { setShowCreateChannelModal(true); }, []); if (!userData) { return <Redirect to="/login" />; } return ( <div> <Header> <RightMenu> <span onClick={onClickUserProfile}> <ProfileImg src={gravatar.url(userData.nickname, { s: '28px', d: 'retro' })} alt={userData.nickname} /> {showUserMenu && ( <Menu style={{ right: 0, top: 38 }} show={showUserMenu} onCloseModal={onCloseUserProfile}> <ProfileModal> <img src={gravatar.url(userData.nickname, { 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={onClickInviteWorkspace}>워크스페이스에 사용자 초대</button> <button onClick={onClickAddChannel}>채널 만들기</button> <button onClick={onLogout}>로그아웃</button> </WorkspaceModal> </Menu> <ChannelList /> <DMList /> {/* {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" value={newUrl} onChange={onChangeNewUrl} /> </Label> <Button type="submit">생성하기</Button> </form> </Modal> <CreateChannelModal show={ShowCreateChannelModal} onCloseModal={onCloseModal} setShowCreateChannelModal={setShowCreateChannelModal} /> <InviteWorkspaceModal show={showInviteWorkspaceModal} onCloseModal={onCloseModal} setShowInviteWorkspaceModal={setShowInviteWorkspaceModal} /> <InviteChannelModal show={showInviteChannelModal} onCloseModal={onCloseModal} setShowInviteChannelModal={setShowInviteChannelModal} /> </div> ); }; export default Workspace; 이건 제가 작성한 WorkSpace 입니다.import Modal from '@components/Modal'; import useInput from '@hooks/useInput'; import { Button, Input, Label } from '@pages/SignUp/styles'; import { IUser } from '@typings/db'; import fetcher from '@utils/fetcher'; import axios from 'axios'; import React, { FC, useCallback } from 'react'; import { useParams } from 'react-router'; import { toast } from 'react-toastify'; import useSWR from 'swr'; interface Props { show: boolean; onCloseModal: () => void; setShowInviteChannelModal: (flag: boolean) => void; } const InviteChannelModal: FC<Props> = ({ show, onCloseModal, setShowInviteChannelModal }) => { const { workspace, channel } = useParams<{ workspace: string; channel: string }>(); const [newMember, onChangeNewMember, setNewMember] = useInput(''); const { data: userData } = useSWR<IUser>('/api/users', fetcher); const { revalidate: revalidateMembers } = useSWR<IUser[]>( userData ? `/api/workspaces/${workspace}/channels/${channel}/members` : null, fetcher, ); console.dir(channel); const onInviteMember = useCallback( (e) => { e.preventDefault(); if (!newMember || !newMember.trim()) { return; } axios .post(`/api/workspaces/${workspace}/channels/${channel}/members`, { email: newMember, }) .then(() => { revalidateMembers(); setShowInviteChannelModal(false); setNewMember(''); }) .catch((error) => { console.dir(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [channel, newMember, revalidateMembers, setNewMember, setShowInviteChannelModal, workspace], ); return ( <Modal show={show} onCloseModal={onCloseModal}> <form onSubmit={onInviteMember}> <Label id="member-label"> <span>채널 멤버 초대</span> <Input id="member" value={newMember} onChange={onChangeNewMember} /> </Label> <Button type="submit">초대하기</Button> </form> </Modal> ); }; export default InviteChannelModal; 이건 제가 작성한 InviteChannelModal입니다.xhr.js:210 GET http://localhost:3090/api/workspaces/sleact/channels/undefined/members 404 (Not Found) dispatchXhrRequest @ xhr.js:210 xhrAdapter @ xhr.js:15 dispatchRequest @ dispatchRequest.js:58 request @ Axios.js:108 Axios.<computed> @ Axios.js:129 wrap @ bind.js:9 fetcher @ fetcher.ts:18 eval @ use-swr.js:392 step @ use-swr.js:43 eval @ use-swr.js:24 eval @ use-swr.js:18 __awaiter @ use-swr.js:14 eval @ use-swr.js:344 softRevalidate @ use-swr.js:532 onFocus @ use-swr.js:550 revalidate_1 @ use-swr.js:73 eval @ use-swr.js:77 eval @ web-preset.js:29그런데 위와 같은 에러가 발생합니다.콘솔에 channel을 출력해도 undefined가 뜹니다.. 그런데 url을 보면 http://localhost:3090/workspace/sleact/channel/테스트채널 이렇게 채널 명이 표시가 되는데 도대체 뭐 때문에 undefined라고 뜨는지 모르겠습니다... 아무리 찾아봐도 알 수가 없어서 글 남깁니다... 분명 WorkSpace의 route에도 오타가 없고 url도 표시가 잘되는데 왜 undefined일까요...
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
31 댓글 등록 삭제 포트폴리오 문제
안녕하세요 ! 포트폴리오 댓글,등록 삭제 과제 풀고있 었는데요 삭제 만드는중에 왜 포폴용 서버 문서에는 저렇게 리턴값을 명시해줘야한다고 돼있는데 코드는export const DELETE_BOARD_COMMENT = gql` mutation deleteBoardComment($password: String, $boardCommentId: ID!) { deleteBoardComment(password: $password, boardCommentId: $boardCommentId) } `; 왜 이렇게 작성해야하는건가요? 풀다보니 저렇게 해야 댓글삭제할때 오류가 나지않더라구요처음에는export const DELETE_BOARD_COMMENT = gql` mutation deleteBoardComment($password: String, $boardCommentId: ID!) { deleteBoardComment(password: $password, boardCommentId: $boardCommentId) { ID } } `;이렇게 작성했는데 오류가 떠서 혹시나 삭제해보니 오류가 나지 않아서 궁금합니다. 점점 복잡해지네요 ㅠㅠ일단 이해는 다 못하지만 댓글삭제, 등록 기능을 구현하긴했는데 다음챕터로 넘어가도될까요 ? 아니면 처음부터 다시 31챕터까지 복습해야할까요?
-
미해결MERN STACK 커뮤니티 : 시작부터 배포까지 알려주는 React
useEffect 두번 사용하는 것
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.두번사용한 이유가axios요청을하고 setPostInfo로 데이터를 저장했지만화면은 렌더링이 끝난 뒤니까 데이터는 가져왔지만화면에는 안띄워져서 useEffect를 두번 사용하신게 맞나요?? 첫번째 useEffect에서 서버 요청후에 만약 PostInfo 데이터가 변한다면 두번째 useEffect가 실행되어 렌더링되므로 데이터를 화면에 띄울 수 있게 되는 것이다.제가 이해한게 맞을까요?? 그렇다면 아래와 같이 처음 useEffect에 PostInfo를 중괄호에 넣으면 왜 안되는지 알 수 있을 까요??넣으니까 서버에 무한 요청만하고 데이터를 화면에 못띄우네요..ㅠㅠ 제가 이해를 잘한 건지 알려주시면 감사드리겠습니다!
-
미해결Slack 클론 코딩[실시간 채팅 with React]
원래 깃허브에 올려주신 파일과 강의 파일이 다른가요...?
안녕하세요.먼저 제로초님 강의 보면서 공부 열심히 하고 있습니다. 감사합니다!. 현재 DMList 만드는 중인데 깃허브에 올려주신 front의 DMList와 제로초님이 강의하면서 작성하시는 DMList의 코드가 서로 다른 부분이 꽤 있던데 원래 그런가요...?영상을 정지해가면서 수정하고 있지만 안보이는 코드가 있어서 많이 헷갈리네요 ㅠㅠ
-
미해결MERN STACK 커뮤니티 : 시작부터 배포까지 알려주는 React
작동은 잘되는데 오류가 뜹니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 검색해보니 undefined가 우려되어 그렇다는데이렇게 바꾸니 괜찮아졌습니다.강의에안나와있는데 괜찮을까요??
-
해결됨비전공자를 위한 진짜 입문 올인원 개발 부트캠프
destructuring 사용하지 않았을 때는 어떻게 코드를 작성해야 하나요?
destructuring을 사용하지 않고 const로 time과 setTime을 정의해서 해봤는데요, 이때는 브라우저에서 클릭을 해도 0초에서 1초로 바뀌지 않습니다. 어떤 부분이 문제인가요?React.useState(0) 뒤에 인덱스 값을 잘못 붙인 건가요?
-
해결됨비전공자를 위한 진짜 입문 올인원 개발 부트캠프
return 후 소괄호가 필수인가요
소괄호를 붙여 해결은 했습니다만, return 뒤에 소괄호를 붙이지 않았을 때 unreachable-code라며 코드가 투명하게 보이고 react app 사이트에도 반영되지 않았는데요 소괄호가 필수인지 궁금합니다참고로 return직후 세미콜론은 저장했더니 자동으로 붙었습니다.
-
해결됨비전공자를 위한 진짜 입문 올인원 개발 부트캠프
콘솔로그가 두번씩 찍힙니다
버튼을 한 번씩 누를 때마다 콘솔창에 콘솔로그가 2번씩 찍히는데 왜 이런 건가요?
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
npx create-react-app 오류 문의드립니다
뭐가 문제일까요? ㅠㅠ
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
axios 설치 오류
안녕하세요!npm install axios --save 명령어로 axios를 설치하였는데이런 문구가 나왔습니다. 혹시 설치가 안된것인가요? 그 이후에 수업을 진행하여"이미지 배너 만들기" 수업을 듣고 코드를작성 후 실행을 하니 영화에 정보가 나오지 않고이런 오류들이 나옵니다.api 키도 사이트에서 잘 가져왔는데.. 혹시 axios 설치가 안되어서 나오는 오류 일까요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
react dev tool 하이라이트 관련 질문
page를 이동하면 보여줄 page컴포넌트가 바뀌고 그 컴포넌트가 첫렌더링 되고그 page의 요소들을 전부 그리는 것으로 알고 있는데요.근데 react dev tool상으로 내부 요소에 하이라이트가 되지 않더라고요.react dev tool에서 보이지 않지만 실제로는 그려지는 것이 맞나요? 회원가입 페이지로 이동했을때의 하이라이트 사진입니다.
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
diaryList 날짜 필터 관련
안녕하세요. 저는 현재 "페이지구현-홈(/)" 강의 18분 쯔음 까지 들었습니다.Home 컴포넌트에서 filter 를 사용하여 현재 날짜에만 dummyList 로 작성해둔 일기가 떠야하는데 뜨질 않습니다.import { DiaryStateContext } from "./App"; import MyButton from "./components/MyButton"; import MyHeader from "./components/MyHeader"; import { useContext, useEffect, useState } from "react"; import DiaryList from "./components/DiaryList"; const Home = () => { const diaryList = useContext(DiaryStateContext); //dummyList 를 받음 const [data,setData] = useState(); const [curDate , setCurDate] = useState(new Date()); const headText= `${curDate.getFullYear()}년 ${curDate.getMonth() + 1}월`; useEffect(()=> { if (diaryList.length >= 1) { const firstDay = new Date( curDate.getFullYear(), curDate.getMonth(), 1 ).getTime(); //현재 년, 월의 1일의 시간을 구함 const lastDay = new Date( curDate.getFullYear(), curDate.getMonth() +1, 0, ).getTime(); setData(diaryList.filter((it) => firstDay <= it.date && it.date <= lastDay)); } },[diaryList, curDate]); useEffect(() => { console.log(data) console.log(diaryList) },[data]) const increaseMonth = () => { setCurDate(new Date( curDate.getFullYear() , curDate.getMonth() + 1, curDate.getDate() )) } const decreaseMonth = () => { setCurDate( new Date(curDate.getFullYear(), curDate.getMonth() - 1, curDate.getDate()) ); }; return ( <div> <MyHeader leftChild={<MyButton text={"<"} onClick={decreaseMonth} />} headText={headText} rightChild={<MyButton text={">"} onClick={increaseMonth} />} /> <DiaryList diaryList={data}/> </div> ); } export default Home;이게 제 Home 컴포넌트이고, 중간에 보면 useEffect 로 data 와 diaryList 를 출력했을때 data 는 빈 배열로 출력되고 diaryList 는 제가 App.js 에서 dummyList 로 작성한 데이터가 잘 출력됩니다. 아무리 봐도 어디가 잘못된건지 모르겠습니다. ㅜㅜ날짜가 잘못된건가 싶어 new Date() 로 다시 확인해봐도 현재 날짜로 잘 나옵니다이건 useEffect 로 출력한 콘솔창 입니다.
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
window.removeEventListener("scroll", () => {});
안녕하세요 강사님🙇♀️다름이 아니라, removeEventListener와 관련되어 질문이 있습니다. 1. window.removeEventListener("scroll", () => {});에서 함수 부분에 아무것도 적어주지 않았는데, 빈 함수를 전달한다면 어떤걸 의미하는건가요? addEventListener과 같은 함수를 적어줘야 하지 않나요?처음 리액트를 공부하는 거라, 많이 부족합니다ㅠㅠ 바쁘시겠지만 도움주시면 감사하겠습니다!(아래는 참고자료 겸 전체코드 첨부드립니다.)import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import "./Nav.css"; export default function Nav() { const [show, setShow] = useState(false); const [searchValue, setSearchValue] = useState(""); const navigate = useNavigate(); useEffect(() => { window.addEventListener("scroll", () => { console.log("window.scrollY", window.scrollY); if (window.scrollY > 50) { setShow(true); } else { setShow(false); } }); return () => { window.removeEventListener("scroll", () => {}); }; }, []); const handleChange = (e) => { setSearchValue(e.target.value); navigate(`/search?q=${e.target.value}`); }; return ( <nav className={`nav ${show && "nav__black"} `}> <img alt="Netflix logo" src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Netflix_2015_logo.svg/170px-Netflix_2015_logo.svg.png" className="nav__logo" onClick={() => (window.location.href = "/")} /> <input value={searchValue} onChange={handleChange} className="nav__input" type="text" placeholder="영화를 검색해주세요." /> <img alt="User logged" src="https://occ-0-4796-988.1.nflxso.net/dnm/api/v6/K6hjPJd6cR6FpVELC5Pd6ovHRSk/AAAABbme8JMz4rEKFJhtzpOKWFJ_6qX-0y5wwWyYvBhWS0VKFLa289dZ5zvRBggmFVWVPL2AAYE8xevD4jjLZjWumNo.png?r=a41" className="nav__avatar" /> </nav> ); }
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
npm i antd styled-components @ant-design/icons 를 하면 오류가 뜹니다
npm i antd styled-components @ant-design/icons터미널에 이 코드를 치면 아래와 같은 오류 메세지가 뜹니다.도와주세요ㅠㅠnpm ERR! Cannot read properties of null (reading 'edgesOut')npm ERR! A complete log of this run can be found in:npm ERR! /Users/hyeonyeongjeong/.npm/_logs/2023-06-23T07_52_15_483Z-debug-0.log
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
npm run dev를 하고 localhost로 들어가면 연결을 거부했다고 뜹니다
npm run dev를 하면 아래와 같은 오류 메세지가 뜹니다그리고 로컬호스트 들어가보면 사이트에 연결할 수 없음이 뜹니다.도와주세요 ㅠㅠ > react-nodebird-front@1.0.0 dev> nextBrowserslist: caniuse-lite is outdated. Please run:npx browserslist@latest --update-dbready - started server on http://localhost:3000node:internal/crypto/hash:71 this[kHandle] = new _Hash(algorithm, xofLen); ^Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/hash:71:19) at Object.createHash (node:crypto:133:10) at module.exports (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/webpack/lib/util/createHash.js:135:53) at NormalModule._initBuildHash (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/webpack/lib/NormalModule.js:417:16) at handleParseError (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/webpack/lib/NormalModule.js:471:10) at /Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/webpack/lib/NormalModule.js:503:5 at /Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/webpack/lib/NormalModule.js:358:12 at /Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/loader-runner/lib/LoaderRunner.js:373:3 at iterateNormalLoaders (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/loader-runner/lib/LoaderRunner.js:214:10) at Array.<anonymous> (/Users/hyeonyeongjeong/Documents/2023project/nodebird/prepare/front/node_modules/loader-runner/lib/LoaderRunner.js:205:4) { opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ], library: 'digital envelope routines', reason: 'unsupported', code: 'ERR_OSSL_EVP_UNSUPPORTED'}Node.js v18.16.1
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
이미지경로를 시퀄라이즈 모델에저장시 post모델에 배열로 저장하지 않고 따로 테이블을 만들어 관계형으로 저장하는이유
1.이미지 경로는 이미지가 여러개일 경우 배열상태로 존재하는데 왜 post 모델에 배열로 저장하지 않고 따로 테이블을 만들어 관계를 짖는 이유를 알수있을까요2.테이블에 배열데이터를 저장하려면 json으로 저장이 될꺼같은데 이 데이터를 text타입으로 바꿔서 저장해야하나요?관계를 지어 테이블을 두개 만드는 방식과 배열데이터를 같은 테이블에 넣는 방식중 머가 더 좋은가요?
-
해결됨초보자도 만들 수 있는 스크롤 인터렉션. 1편 자바스크립트
죄송합니다만 해당 프로젝트를 리엑트로 수정해서 만들어보고있는중에 질문드립니다.
코드로보시면 간단합니다.왠만한건 다돌아가기 때문에 해석할 필요는 없으실겁니다.테일윈드backgroundImage 를 단축어로설정하여 bg-sky2 를사용하면 사진이 불러와집니다. 모든것이 정상 작동잘됍니다. 아래는 제가 작성한 코드중 일부분입니다. <div className={`${ scrollPercent >= 25 && scrollPercent < 50 ? "opacity-100 " : "opacity-0 " } block absolute h-full bg-sky2 transition-opacity duration-500`} ></div>이때 absolute 를 사용하였을떄 bg-sky2 이미지가 안보이게됍니다.일부분 버그인줄 알았습니다. 그래서 다른 백그라운드 색상을 바꾸어보았습니다.bg-sky2 ==>(교체) bg-red-400 동일하게 안보입니다.하지만absolute 를 사용하지 않으면 4개가 스택처럼 쌓이지만 정상적이게 원하는퍼 센테이지에 올떄 없어지고 생성됍니다.고민중이미지로 만들었는데 정상작동 하였습니다.하지만 저는backgroundImage 로넣는것이 필터다 backgroundFixed 등 여러가지 활용이 된다고 생각하여 질문드립니다. <img className={`${ scrollPercent >= 75 && scrollPercent < 102 ? "opacity-100 " : "opacity-0 " }block absolute h-full transition-opacity duration-500`} src="/images2/motion_sky4.gif" alt="motion_moon" /> 요약absolute을 사용하면 다돌아가던것이 왜인지 안돌아갑니다.개발환경은 next.js tailwind 입니다.(취업못하고 공부용입니다.) 전체코드는 다음과같습니다"use client"; import React, { useRef, useEffect, useState } from "react"; import motion_sky1 from "@/../../public/images2/motion_sky1.gif"; function Page() { const [scrollPercent, setScrollPercent] = useState(0); const scrollBody = useRef(null); console.log(scrollPercent); useEffect(() => { const handleScroll = () => { const scrollRealHeight = document.documentElement.scrollHeight - window.innerHeight; const scrollTop = window.scrollY; const percentScroll = Math.round((scrollTop / scrollRealHeight) * 100); setScrollPercent(percentScroll); }; window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); return ( <div ref={scrollBody} className="relative left-0 top-0 h-6000 w-full "> <div>내용</div> {/* <img className={`${ scrollPercent < 25 ? "opacity-100 " : "opacity-0 " }block absolute h-full bg-black transition-opacity duration-500 `} src="/images2/motion_sky1.gif" alt="motion_moon" /> <img className={`${ scrollPercent >= 25 && scrollPercent < 50 ? "opacity-100 " : "opacity-0 " } block absolute h-full bg-teal-500 transition-opacity duration-500`} src="/images2/motion_sky2.gif" alt="motion_moon" /> <img className={`${ scrollPercent >= 50 && scrollPercent < 75 ? "opacity-100 " : "opacity-0 " }block absolute h-full bg-red-400 transition-opacity duration-500`} src="/images2/motion_sky3.gif" alt="motion_moon" /> <img className={`${ scrollPercent >= 75 && scrollPercent < 102 ? "opacity-100 " : "opacity-0 " }block absolute h-full bg-blue-500 transition-opacity duration-500`} src="/images2/motion_sky4.gif" alt="motion_moon" /> */} <div className={`${ scrollPercent < 25 ? "opacity-100 " : "opacity-0 " }block absolute Fixed z-50 h-full bg-sky1 transition-opacity duration-500 `} ></div> <div className={`${ scrollPercent >= 25 && scrollPercent < 50 ? "opacity-100 " : "opacity-0 " } block absolute h-full bg-sky2 transition-opacity duration-500`} ></div> <div className={`${ scrollPercent >= 50 && scrollPercent < 75 ? "opacity-100 " : "opacity-0 " }block absolute h-full bg-red-400 transition-opacity duration-500`} ></div> <div className={`${ scrollPercent >= 75 && scrollPercent < 102 ? "opacity-100 " : "opacity-0 " }block absolute h-full bg-blue-500 transition-opacity duration-500`} ></div> <div className="motion_ggang"> <figure className="ch_body"> {/* 몸 */} <img className="fixed h-40 w-32 top-12 left-7" src="/images2/motion_body2.png" alt="motion_body2" /> </figure> {/* 손 */} <figure className="ch_hand_right"> <img className="fixed h-40 w-32 top-12 left-7" src="/images2/motion_hand_right.png" alt="motion_hand_right" /> </figure> </div> {/* 달 */} <figure className="motion_moon"> <img className="fixed h-40 w-32 top-12 right-3" src="/images2/motion_moon.png" alt="motion_moon" /> </figure> </div> ); } export default Page;
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
javascript 내장함수 리뷰 파트 질문
let isStarted = false; let auth = () => { if(isStarted === false){ // 타이머가 작동중이 아닐때 타이머가 동작하게 함 isStarted = true document.getElementById("finish").disabled = false const token = String(Math.floor(Math.random() * 1000000)).padStart(6,"0") document.getElementById("target").innerText = token document.getElementById("target").style.color= "#" + token let time = 180 let timer timer = setInterval(function() { if(time >= 0 ){ let min = Math.floor( time / 60 ) let sec = String (time % 60).padStart(2,"0") // console.log(min + ":" + sec) document.getElementById("timer").innerText= min + ":" + sec time = time - 1 } else { document.getElementById("finish").disabled=true isStarted = false clearInterval(timer) } },1000) } else { // 타이머가 작동중일때 } } let isStarted를 False로 주고auth함수 안에 if문에서 isStarted가 False 일때1.isStarted에 아무것도 할당 안하면 else문으로 넘어가지않는다.2.처음에 isStarted에 true를 할당하고 마지막에 false를 할당한다if문 부분에 설명이모든게 낯선 제 머리로는 이 로직이 이해가 안되네요 ㅠㅠ왜 true를 줬는지 ture를 주면 어떤일이 일어나는지아무것도 안줬을때는 어떤일이 일어나는지 조금 더 자세한 설명 부탁드립니닷.확실히 javascript파트는 어렵습니다.ㅠㅠㅠ
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
새글추가시 새로생신게시글 id
더미데이터가 id 1부터 id 5까지 총 5개의 게시물이 존재하는데, 새글을 한번 추가하면 그 새글이 id 0으로 추가가 되고, 다시 한번 더 추가시 새글이 id 1로 추가가 됩니다 ㅠㅠ 그래서 새글 추가시 게시글정렬도 꼬이게 보여요ㅠㅠ 왜 이런 오류가 난거지 궁금합니다. 코드샌드박스 주소 첨부합니다!https://codesandbox.io/s/hungry-bogdan-59h25q