묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
카카오 로그인 serializer 구현
안녕하세요 제로초님.passport-kakao를 이용해서 kakao 로그인을 구현해보고 있습니다.로그인과 회원가입 까지는 잘 되는데, serializer을 통해서 cookie가 저장되지 않습니다. kakako.strategy.tsimport { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-kakao'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import * as _ from 'lodash'; import { AuthService } from './auth.service'; import { Platform } from 'src/entities/common/Platforms'; @Injectable() export class KakaoStrategy extends PassportStrategy(Strategy) { constructor( private readonly configService: ConfigService, private authService: AuthService, ) { super({ clientID: configService.get<string>('KAKAO_REST_API_KEY'), clientSecret: configService.get<string>('KAKAO_CLIENT_SECRET'), callbackURL: configService.get<string>('KAKAO_REDIRECT_URI'), }); } async validate(accessToken, refreshToken, profile, done) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { _json: { id, properties: { nickname, profile_image: profileImage }, kakao_account: { email }, }, } = profile; const user = await this.authService.findOrCreateUser( email, nickname, Platform.KAKAO, ); return done(null, user); } } 아래에 있는 kakao-auth.guard.ts와 kakao.serializer.ts는 로컬 로그인과 다른 점이 없을 것 같아서 그대로 썼습니다. kakao-auth.guard.tsimport { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class KakaoAuthGuard extends AuthGuard('kakao') { async canActivate(context: ExecutionContext): Promise<boolean> { const can = await super.canActivate(context); if (can) { const request = context.switchToHttp().getRequest(); await super.logIn(request); } return true; } } kakao.serializer.tsimport { Injectable } from '@nestjs/common'; import { PassportSerializer } from '@nestjs/passport'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { AuthService } from './auth.service'; import { Users } from 'src/entities/Users'; @Injectable() export class KakaoSerializer extends PassportSerializer { constructor( private readonly authService: AuthService, @InjectRepository(Users) private usersRepository: Repository<Users>, ) { super(); } serializeUser(user: Users, done: CallableFunction) { done(null, user.id); } async deserializeUser(userId: string, done: CallableFunction) { return await this.usersRepository .findOneOrFail({ where: { id: +userId }, select: ['id', 'email', 'nickname'], }) .then((user) => { done(null, user); }) .catch((error) => done(error)); } }이처럼 작성하면, 로그인 시 세션에 쿠키가 저장되어야 하는게 아닌가요?사실 강의에서 설명해주신 내용중 이해가 잘 가지 않는 부분이 있습니다.localStrategy에서 done(null, user) -> local-auth.guard.ts에서 super.logIn(request) -> local serializer 에서 serializeUser() 을 호출한다고 말씀하셨는데, 세 가지 파일에서 LocalStrategy, LocalAuthGuard, LocalSerializer을 서로 명시적으로 연결해준적이 없음에도 불구하고 어떻게 서로 잘 알아서 호출되는지 궁금합니다.그냥 앞에 모두 Local이 붙어서, 잘 찾아서 호출되는 건가요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
ManyToMany 테이블이 자동으로 만들어지지 않습니다..
import { ProductCategory } from 'src/apis/productsCategories/entites/productCategory.entity'; import { ProductSaleslocation } from 'src/apis/productsSaleslocations/entities/productSaleslocation.entity'; import { ProductTag } from 'src/apis/productsTags/entities/productTag.entity'; import { User } from 'src/apis/users/entities/user.entity'; import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToOne, PrimaryGeneratedColumn, } from 'typeorm'; @Entity() export class Product { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; @Column() description: string; @Column() price: number; @Column({ default: false }) isSoldout: boolean; @JoinColumn() // 1:1 연결에서는 두 테이블 중 중심을 정하는 JoinColumn을 달아주어야한다. @OneToOne(() => ProductSaleslocation) // 일대일 연결. 어떤 테이블이랑 연결될지 표기. ProductSaleslocation 테이블과 연결 할 것이다. productSaleslocation: ProductSaleslocation; // 그 때 사용되는 Column은 productSaleslocation이고 타입은 다음과 같다, FK @ManyToOne(() => ProductCategory) // many가 Product 한개인게 Category productCategory: ProductCategory; // FK @ManyToOne(() => User) user: User; @JoinTable() // ManyToMany는 둘 중 하나에 JoinTable 작성 @ManyToMany(() => ProductTag, (productTags) => productTags.products) // 상대방 입장에서 나를 볼 때 products productTags: ProductTag[]; // 객체가 여러개이기 떄문에 객체 배열타입 사용 } import { Product } from 'src/apis/products/entities/product.entity'; import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class ProductTag { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; @ManyToMany(() => Product, (products) => products.productTags) products: Product[]; }ManyToMany 설정했는데.. product_product_tags_product_tag 테이블이 자동으로 생성이 안되네요. 코드 말고 건드려줘야 할 부분이 있나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
폴더, 파일, 함수 생성시 s붙이는 기준
product vs products 와 같이파일 및 폴더 생성시 s를 붙이는 기준이좀 해깔리는데,어디에서 설명해주셨는지 기억이 안나서질문 드립니다~답변 주시면 감사하겠습니다~1.apis 아래 1depth 폴더에는 s를 붙임apis/products 2. entities 폴더 내부 파일 s 안붙임entities/product.entity.ts 3.module.ts, resolver.ts, service.ts 에는 s붙임src/products/products.module.tssrc/products/products.resolver.tssrc/products/products.service.ts
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
포트폴리오 관련 질문 - 오늘 본 상품
안녕하세요. 포트폴리오 작성 중 여러 방법을 시도해 보다 도저히 해결방법을 잘 모르겠어서 질문드립니다.구현하고 싶은 것 : 오늘 본 상품 목록을 다른 페이지에서 구현 하는 것이 아닌 여러 페이지의 본문 영역 옆에 상시 뜨도록 설계 하는 것, recoil을 이용하지 않고 localStorage 를 이용하여 구현하는 것 입니다. 아래 사진은 현재 진행 과정 입니다.아래는 현재 코드입니다sidebar.tsx import { useEffect, useState } from "react"; import * as S from "./sidebar.style"; import type { IUseditem } from "../../../../commons/types/generated/types"; import { LikeFilled } from "@ant-design/icons"; import { getPrice } from "../../../../commons/libraries/price"; export default function SideBar(): JSX.Element { const [items, setItems] = useState<IUseditem[]>([]); useEffect(() => { const storedItems = localStorage.getItem("todaylist"); if (!storedItems) return; setItems(JSON.parse(storedItems)); }, []); return ( <S.SideBarWrapper> <S.SideBarTitle>오늘 본 상품</S.SideBarTitle> {items .filter((el) => el) .map((el) => ( <S.SideBarContents key={el._id}> <S.SideBarP> <LikeFilled style={{ color: "#ffd903" }} /> {el.pickedCount} </S.SideBarP> {el.images && ( <S.SidaBarImg src={`https://storage.googleapis.com/${el.images[0]}`} /> )} <S.SidebarDetail> <S.SideBarName>{el.name}</S.SideBarName> <S.SideBarRemarks>{el.remarks}</S.SideBarRemarks> <S.SideBarPrice>{getPrice(el.price)}</S.SideBarPrice> </S.SidebarDetail> </S.SideBarContents> ))} </S.SideBarWrapper> ); } 문제점useEffect 부분에서 storedItems 가 업데이트 될 때마다, 리렌더링을 해주고 싶어, 종속성 배열에 items state를 넣으니 ⚠ Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.관련 오류가 뜹니다. 여러 방법을 시도해도 옳은 방법을 잘 모르겠어서 질문 남깁니다.
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
게시판만들다가 질문드립니다
import "./App.css"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import MainPage from "./pages/MainPage"; import Board from "./pages/Board"; import { useEffect } from "react"; function App() { useEffect(() => console.log("app is loading"), []); return ( <BrowserRouter> <Routes> <Route path="/" element={<MainPage />}></Route> <Route path="/board/:bbsId" element={<Board />}></Route> <Route path="/board/:bbsId/new" element={<Board />}></Route> </Routes> </BrowserRouter> ); } export default App; import React, { useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; // useParams를 import import BoardList from "../pagesComponent/BoardList"; import BoardEdit from "../pagesComponent/BoardEdit"; import BoardView from "../pagesComponent/BoardView"; import Layout from "../layout/Layout"; import axios from "axios"; export const BbsSettingContext = React.createContext(); const Board = () => { const { bbsId } = useParams(); // const [currentUrl, setCurrentUrl] = useState(null); const [boardSettData, setBoardSettingData] = useState(null); useEffect(() => { let mode = window.location.pathname.split("/")[3] == null ? "list" : window.location.pathname.split("/")[3]; console.log(`mode::::::::::::::${mode}`); setCurrentUrl(mode); axios .get("http://localhost:8080/board/" + bbsId) .then((response) => { const boardSettData = response.data.bbsEntity; console.log(boardSettData); setBoardSettingData(boardSettData); }) .catch((error) => console.log(error)); }, [currentUrl]); return ( <BbsSettingContext.Provider value={boardSettData}> {currentUrl == "list" ? ( <Layout> <BoardList /> </Layout> ) : currentUrl == "new" ? ( <Layout> <BoardEdit /> </Layout> ) : currentUrl == "edit" ? ( <Layout> <BoardEdit /> </Layout> ) : currentUrl == "view" ? ( <Layout> <BoardView /> </Layout> ) : ( <BoardList /> )} </BbsSettingContext.Provider> ); }; export default Board; import React from "react"; import { useContext, useHistory } from "react"; import { BbsSettingContext } from "../pages/Board"; import PageNationPage from "./PageNationPage"; import { useNavigate } from "react-router-dom"; const BoardList = () => { const boardSetData = useContext(BbsSettingContext); console.log(boardSetData); const Navigate = useNavigate(); const handleBoardEdit = () => { // 원하는 동작을 수행할 코드를 여기에 추가 console.log("쓰기로 이동"); Navigate("/board/1/new"); }; return ( <div className="BoardList"> <table className="bbsTable"> <colgroup> <col style={{ width: "10%" }} /> <col style={{ width: "40%" }} /> <col style={{ width: "10%" }} /> <col style={{ width: "20%" }} /> <col style={{ width: "10%" }} /> </colgroup> <thead> <tr> <th scope="col">번호</th> <th scope="col">제목</th> <th scope="col">작성자</th> <th scope="col">등록일</th> <th scope="col"> 조회</th> </tr> </thead> </table> <PageNationPage /> <button onClick={handleBoardEdit}>쓰기</button> </div> ); }; export default BoardList; import React from "react"; import { useState, useEffect, useContext } from "react"; import { BbsSettingContext } from "../pages/Board"; const BoardEdit = () => { const boardSetData = useContext(BbsSettingContext); console.log(boardSetData); return <div>BoardEdit</div>; }; export default BoardEdit; 안녕하세요 다름이 아니라 일기장 보고 게시판을 응용해서 만들던 도중에 안되는게 있어서 질문드립니다.http://localhost:3000/board/1이 리스트로 나오는데요 ...거기서 쓰기를 누르면 http://localhost:3000/board/1/new으로 위에 url은 바뀌는데밑에 ui는 전혀 바뀌질 않습니다 .그리고 Board.js에 useEffect쪽에 콘솔로 찍어봐도 들어오지가 않는데 이유를 좀 알수있을까요 ????? 근데 쓰기 버튼말고 그냥 직접 url을 입력하고 enter를 입력하면 이동합니다 .
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
타입스크립트 설치파트에서 에러가 납니다.
타입스크립트 설치하고 yarn dev 한 이후, yarn add --dev @types/react @types/node 을 통해추가 설치 ? 를 진행하려고 보니 강사님은 아무 에러 없이 잘 진행 되는 반면에 저는 이러한 에러가 뜹니다... ㅠ
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
faker 사용 후 postData.split is not a function 에러 질문
이전에는 잘 되었는데 faker로 더미데이터 사용 후에 다음과 같은 에러가 뜹니다!faker 버전 이슈를 보고 삭제 후 npm i -D faker@5 로 재설치했는데 오류가 해결되지 않았습니다ㅠ console.log 찍어본 postData의 타입이랑 에러메시지 입니다!4. WrappedApp created new store with withRedux(NodeBird) { initialState: undefined, initialStateFromGSPorGSSR: undefined }type : stringtype : functionTypeError: postData.split is not a functionat PostCardContent (C:\Users\pc\react-nodebird\prepare\front\.next\server\pages\index.js:1131:13)at processChild (C:\Users\pc\react-nodebird\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3043:14)at resolve (C:\Users\pc\react-nodebird\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:2960:5)at ReactDOMServerRenderer.render (C:\Users\pc\react-nodebird\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3435:22)at ReactDOMServerRenderer.read (C:\Users\pc\react-nodebird\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3373:29)at renderToString (C:\Users\pc\react-nodebird\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3988:27)at Object.renderPage (C:\Users\pc\react-nodebird\prepare\front\node_modules\next\dist\next-server\server\render.js:50:851)at Document.getInitialProps (C:\Users\pc\react-nodebird\prepare\front\.next\server\pages\_document.js:264:19)at loadGetInitialProps (C:\Users\pc\react-nodebird\prepare\front\node_modules\next\dist\next-server\lib\utils.js:5:101)at renderToHTML (C:\Users\pc\react-nodebird\prepare\front\node_modules\next\dist\next-server\server\render.js:50:1142) PostCardContent.js 코드 중 의심스러운 부분입니다const PostCardContent = ({ postData }) => ( <div> {postData.split(/(#[^\s#]+)/g).map((v, i) => { if (v.match(/(#[^\s#]+)/)) { return <Link href={`/hashtag/${v.slice(1)}`} key={i}><a>{v}</a></Link>; } return v; })} </div> ); PostCardContent.propTypes = { postData: PropTypes.string.isRequired, };
-
미해결지금 당장 NodeJS 백엔드 개발 [사주 만세력]
API접속이 안 됩니다.
Node js는 정상적으로 실행되었습니다.API POSTMAN 호출시 다음 에러가 발생합니다.Frontend를 실행시켜서 해 봐도 동일한 에러입니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
.indexOf 메소드 사용 질문
안녕하세요, indexOf 메소드를 사용하다가 -1 값이 변환되었습니다. 파이썬에서는 인덱스가 -1이라면 맨마지막에 있는 인덱스 순서를 의미하는데 자바스크립트는 의미가 다른가요?자바스크립트에서 가지는 '-1'의 의미가 궁금합니다. 코드를 보시면 제가 indexOf 메소드 값 안에 오타를 넣었습니다.오류가 날 줄 알았는데 오타의 인덱스 값이 -1이 반환되어서 -1 값이 나온 이유에 대해 설명 부탁드립니다. 감사합니다. 수업 잘 듣고 있습니다. :)
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
Promise, resolve, setTimeout에 대한 질문입니다.
async function aaa() { console.log(1); console.log(2); await new Promise((resolve, reject) => { setTimeout(resolve, 3000); }).then(() => { console.log("히히히"); }); console.log(3); } aaa();async function aaa() { console.log(1); console.log(2); await new Promise((resolve, reject) => { setTimeout(() => {}, 3000); }).then(() => { console.log("히히히"); }); console.log(3); } aaa(); 맨위의 코드는 12히히히3 이렇게 잘 찍힙니다. 위의 코드에서 setTimeout(resolve,3000) 에서 resolve를 ()=>{} 로 바꾸니, 12 이렇게 찍힙니다. resolve라는 것을 쓰지 않음으로써 then으로 가지 못해 console.log('히히히')가 동작을 하지 않는 것은 이해가 되는데, promise 외부 코드인 console.log(3); 이 동작하지 않는건 이해가 되지 않습니다. resolve에 뭔가 더 특별한 기능이 더 있는 건가요??
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
node.js 로그인 기능을 async로 변경했는데 json 출력값이 이상해요
안녕하세요.따라하며 배우는 노드, 리액트 시리즈 12강을 듣고 async를 이용하여 로그인 코드를 다음과 같이 변경 했습니다.app.post('/login', async (req, res) => { User.findOne({email:req.body.email}).then((user)=>{ if(!user){ return res.json({ loginSuccess:false, message:"제공된 이메일에 해당하는 유저가 없습니다." }) } user.comparePassword(req.body.password, (err, isMatch)=>{ if(err) return res.status(400).send(err); if(!isMatch) return res.json({ loginSuccess:false, message:"비밀번호가 틀렸습니다."}) user.generateToken((err, user) => { if(err) return res.status(400).send(err); res.cookie("x_auth", user.token) .status(200) .json({loginSuccess:true, userId : user._id }); }) }) }) }) 문제 없이 잘 실행이 되는 것 같은데 (분기점에 따라서 message는 제대로 출력됩니다.)다만 generateToken후에 json에서 설정한 loginSuccess, userId 만 보이는게 아니고 이렇게 user 정보가 다 나옵니다. loginSuccess은 출력이 안되고요.이유가 찾을 수 없어 여기에 질문드립니다ㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
파이널 과제도중 질문
파이널 과제중에 html이랑 css는 어느정도 다를수있게된거같은데 타이머나 인증번호쪽 js가 쫌 안되더라고요..이걸 공부를 어떻게해야할지 고민입니다파이널과제를 완벽하게 할수있을때까지 복습을해야할지..아니면 다음 커리큘럼이 js니까 일단 진도를 나가야할지 고민입니다
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
중간 테이블 질문
엔티티 작성할 때 @ManyToMany와 @JoinTable을 사용해서 중간 테이블을 설정해주고, 따로 또 ~Members엔티티를 작성해서 중간 테이블을 설정해줬는데 이게 겹치는 문제는 없나요? 워크 벤치에 생성된 중간 테이블은 하나밖에 없던데 그건 @JoinTable에 의해 생성된 중간 테이블인가요? 직접 작성한 중간 테이블인 ~Members엔티티인가요?
-
해결됨React + GPT API로 AI회고록 서비스 개발 (원데이 클래스)
const handleEnter 문에 궁금한게 있습니다.
setUserInput("")을 하면 userInput 값이 ""로 바뀌고그다움 num 선언문에 ""의 숫자변환값이 들어가는게 아닌가 궁금합니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
NODE로 프로그램을 WINDOW 설치 프로그램으로 만들고싶습니다.
제가 만든 NODEJS 프로그램을 한글처럼 WINDOW 환경에서 통합설치 프로그램 하나만 설치하면 DB, NODE 프로그램이 설치되도록 하고싶은데 어떤 방법이 있고 구글에 어떻게 검색해야 하는지 궁금합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
access token 관련 질문드립니다.
안녕하세요 강의를 다 듣고 개인 포트폴리오 제작중에 있습니다.현재 로그인 부분을 구현중인데, 포인트 충전이라던가 마이페이지 접근시, 비밀번호 변경 시 등의 경우에 인가(여기선 fetchUser)를 받아야 한다고 이해했습니다. 그러려면, 강의에선 아래 사진처럼 header에 토큰을 넣어서 보내었습니다.하지만 직접 프론트엔드를 구축해서 api 호출하려고 하니 header에 토큰을 넣어줘야 하는데, 현재 로그인시 그냥 토큰 값인 문자열을 리턴할 뿐 엑세스토큰을 저장하는 곳이 없습니다.보통 액세스토큰을 저장할 때 변수, 로컬스토리지, 세션스토리지, 쿠키 중 무엇을 가장 많이 사용하나요?섹션 13-11의 강의에서 처럼 변수에 액세스토큰을 저장하는 경우를 생각해 봤습니다. 그러면 인증하는 컴포넌트(ex: login)와 인가를 받는 컴포넌트(ex: 포인트 충전)가 다를 때 컴포넌트에서 token을 변수로 저장하더라도 다른 컴포넌트에서는 사용 못할텐데 recoil같은 라이브러리를 사용해서 전역변수로 사용해야 하는지 궁금합니다. 아래는 프론트엔드의 login 컴포넌트를 예시를 적어보았습니다. const [token, setToken] = useState(""); await axios.post("http://localhost:5656/graphql", { query: ` mutation { login(id: "${inputId}", password: "${inputPw}") } `, }) .then(res => { setToken(res.data.data.login); } }) 감사합니다.
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
서비스 중 API 수정이 어렵다는 부분에 궁금한 점이 있습니다
7:47부터 말씀하시는 내용에 대한 질문입니다.API 설계가 잘못되었더라도 서비스 도중이면 수정하기가 어렵다고 하셨는데요.예시로 보여주신 것처럼 API 내에서 쓰이는 함수는 섣불리 건들면 안된다는건 이해가 되었습니다. 그런데 (':url/members/:id')에서 (':url/users/:id')로 고치는 것과 같이 URL 수정에는 어떤 이유로 어려움이 있는지가 궁금합니다.제가 생각하기에는 개발자가 아닌 일반적인 사용자들은 프론트엔드에서 버튼과 같은 UI를 클릭해서 이용하지, 위 URL을 전부 입력해서 사용하는 경우는 잘 없지 않을까? 라고 생각이 들거든요.혹시 같이 작업 중인 동료 개발자들에게 혼란을 줄 수 있는 이유에서일까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
next export 질문있습니다
next 14 버전부터 next export 가 없어지고 next.config.js 파일에서 output: "export" 로 대체되었다는데 이대로 진행해도 문제 없을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
퀴즈5 비밀번호 유효성 검증
비밀번호와 비밀번호 확인이 서로 일치하는지 검증하는 코드를 어떻게 짜야할 지 모르겠어요.. 현재 코드로 하면 에러가 납니다..! 봐주시면 감사하겠습니다ㅠㅠ 해당코드 //문제부분!!!!!!!!!!!!!!!!!!!!********* 으로 해놓았습니다!! import { useState } from 'react'; export default function signUpPage() { //이메일, 비밀번호 담기 const [ email, setEmail ] = useState(""); const [ password, setPassWord ] = useState(""); const [ Repassword, setRePassWord ] = useState(""); //이메일 에러 const [ emailError, setEmailError ] = useState(""); //비밀번호 에러 const [ passWordError, setPassWordError ] = useState(""); //비밀번호확인 에러 const [ RepassWordError, setRePassWordError ] = useState(""); //이메일 const onChangeEmail = (event) =>{ //이벤트 핸들러 console.log(event); console.log(event.target); //작동된 태그 console.log(event.target.value); //작동된 태그에 입력된 값 //변경된 이메일 값을 넣음 setEmail(event.target.value); if(event.target.value !== ''){ //내용 입력시 에러 없애주는거 setEmailError(""); } } const onChangePassWord = (event) => { setPassWord(event.target.value); if(event.target.value !== ''){ setPassWordError(""); } } //문제부분!!!!!!!!!!!!!!!!!!!!********* const onChangeRePassWord = (event) => { // const currentPassWord = event.target.value; // setRePassWord(currentPassWord); // if(password === currentPassWord){ // setRePassWordError(""); // } setRePassWord(event.target.value); if((password === Repassword()) || (event.target.value !== '')){ setRePassWordError(""); } } //등록하기 버튼 에러검증 const onClickSign = () => { //이메일 @ 검증 //includes("") 해당 문자가 있냐 없냐 if(email.includes("@") === false) { setEmailError("이메일이 올바르지 않습니다. @ 형태로 입력해주세요!") } if(!password){ setPassWordError("비밀번호를 입력해주세요") } //문제부분!!!!!!!!!!!!!!!!!!!!********* if((password !== Repassword) || (!Repassword)){ setRePassWordError("비밀번호를 확인해주세요") } //회원가입 완료 if(email && password === Repassword) { alert("회원가입이 완료되었습니다") } } return( <> 이메일: <input type="text" onChange={onChangeEmail} /> <div>{emailError}</div> 비밀번호 :<input type="text" onChange={onChangePassWord} /> <div>{passWordError}</div> 비밀번호확인 :<input type="text" onChange={onChangeRePassWord} /> <div>{RepassWordError}</div> <button id="submit" onClick={onClickSign}>회원가입</button> </> ) }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
jest 오류 'Assertion' 형식에 'toBe' 속성이 없습니다.
'Assertion' 형식에 'toBe' 속성이 없습니다. 이 오류가 jest관련 toBe, toEqual, toBeInTheDocument등에 다 뜹니다