HTML 회원가입
해결됨
[코드캠프] 시작은 프리캠프
수업에서 그 회원가입 페이지 만들고 다음 날에 다시 켜니까 코드는 바뀐게 전혀 없고 잘 저장되어 있는데 페이지에 다시 들어가니까 글씨가 이상한 말로 적혀있어요! 근데 또 빨간 테두리는 잘 반영이 됩니다… 뭐가 문제인가요???!
- HTML/CSS
- javascript
173만명의 커뮤니티!! 함께 토론해봐요.
해결됨
[코드캠프] 시작은 프리캠프
수업에서 그 회원가입 페이지 만들고 다음 날에 다시 켜니까 코드는 바뀐게 전혀 없고 잘 저장되어 있는데 페이지에 다시 들어가니까 글씨가 이상한 말로 적혀있어요! 근데 또 빨간 테두리는 잘 반영이 됩니다… 뭐가 문제인가요???!
미해결
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
현재 객체 localStorage저장 부분의 인강을 보다 궁금한점 있어 질문을 드립니다. const saveItemsFn = function () { const saveItems = []; for (let i = 0; i < todoList.children.length; i++) { const todoObj = { contents: todoList.children[i].querySelector("span").textContent, complete: todoList.children[i].classList.contains("complete"), }; saveItems.push(todoObj); } localStorage.setItem("saved-items", JSON.stringify(saveItems)); }; 현재 자바스크립트 코드 제일 마지막 부분에 saveItemsFn함수가 저장하는 부분이니 이 함수안에 localStorage.setItem을 사용해서 로컬스토리지에 저장을 하는것까지는 이해가 되었는데 저장된걸 가져오기 위해 const savedTodoList = localStorage.getItem("saved-items"); localStorage.getItem을 사용하는데 여기서 첫번째로 이 코드 위치가 다시 제일 위쪽에 작성이 되었는지 궁금하고 두번째로 이 코드가 saveItemsFn 함수 안에 작성이 되지 않은 이유는 getItem이 저장하는 코드가 아니기때문에 saveItemsFn안이 아닌 따로 다시 작성이 된것인가요?
해결됨
Next + React Query로 SNS 서비스 만들기
https://www.inflearn.com/questions/1268586/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%90%EB%9F%AC-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4 여기에서 질문했던 로그인 관련 문제입니다. 지금 현재 로그인 후 로그아웃 후 다른 아이디로 재로그인시에 로그아웃 버튼에 session정보가 제대로 안들어가는 것 같습니다. 처음 로그인 했을 때 로그아웃에 session 정보가 들어가고, 로그아웃 후 다른 아이디로 재로그인시에 로그아웃버튼에 로그아웃전의 계정의 정보가 들어가 있습니다. 백엔드 서버 콘솔에는 정보가 제대로 들어가 있지만, let session = await auth(); 에서 session정보가 제대로 안 받아지는건지, 아니면 캐싱된 정보가 계속 쓰이는 건지 모르겠지만, 정보가 제대로 안들어갑니다. 물론 새로고침시에 정상적으로 정보가 들어가집니다. 제 프로젝트에서 문제가 있는건가 싶어서, 코드를 비교해보고 next, next-auth 버전을 바꿔보기도 했지만, 해결이 안되어서, 배포된 https://z.nodebird.com/ 링크로도 해보았는데 똑같은 버그가 있는 것 같아서 질문드립니다. 무엇이 문제인지 궁금합니다. 좋은 하루 보내세요!
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
섹션 10에서 graphql codegen 설치하려는데요 강의에서는 yarn add -D @graphql-codegen/cli 을 설치하라고 하는데 지금 설치하려고 사이트에 들어가니 yarn add --dev typescript @graphql-codegen/cli 로 되어 있는데 같은 건가요? 그냥 아래 명령어 실행해도 되나요?
미해결
Next + React Query로 SNS 서비스 만들기
선생님 안녕하세요 사이드플젝하면서 다시 보고있는데, 클라이언트 사이드에서 useSession데이터가 없어서 질문 드립니다. import NextAuth from "next-auth" import Credentials from "next-auth/providers/credentials" export const { handlers, signIn, signOut, auth } = NextAuth({ pages: { signIn: '/login', newUser: '/signup', }, providers: [ Credentials({ // You can specify which fields should be submitted, by adding keys to the `credentials` object. // e.g. domain, username, password, 2FA token, etc. credentials: { id: {}, password: {}, }, authorize: async (credentials) => { console.log(credentials, '-------------------credentials'); const authResponse = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(credentials), }) console.log(authResponse.ok, '-----------------------------authResponse.ok'); if (!authResponse.ok) { return null; } let user = await authResponse.json(); // return user object with the their profile data console.log(user, '--------------------------------'); return { id: user.id, email: user.id, name: user.nickname, image: user.image, ...user, } }, }), ], }) 먼저 auth.ts에서 유저 정보를 잘 받아와서 return해주는 것 확인하고, /profile/page.ts (서버클라이언트) /profile/_component/logoutButton (클라이언트 컴퍼넌트)에서 각각 세션을 확인해 봤습니다. (서버 컴포넌트) import { auth } from '@/auth'; const session = await auth(); console.log(session, '------------server side session'); if (!session?.user) { redirect('/login'); } (클라리언트 컴포넌트) 'use client'; import { Button } from '@/components/ui/button'; import { useCallback } from 'react'; // client component에서만! import { signOut, useSession } from 'next-auth/react'; import { useRouter } from 'next/navigation'; export default function LogoutButton() { const router = useRouter(); const { data: me } = useSession(); const onLogout = useCallback(() => { signOut({redirect: false}).then(() => {router.replace('/')}); }, [router]); console.log(me, '------------client side session'); if (!me?.user) return null; return ( <Button className='w-full' onClick={onLogout}>로그아웃</Button> ) } 결과로 와같이 클라리언트 사이드에서는 데이터가 없더라구요. 혹시 어떤부분을 좀 더 봐야할지 알 수 있을까요? 그리고 useSession을 호출하면서 Failed to load resource: the server responded with a status of 404 (Not Found) app-index.js:33 ClientFetchError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON at fetchData (client.js:49:22) at async getSession (react.js:109:21) at async __NEXTAUTH._getSession (react.js:270:43) session 404가 계속나오는데 제가 잘못 호출하고있는건지 궁금합니다.
미해결
[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
안녕하세요. 열심히 강의 따라가고 있었는데, 실수로 작업하던 소스파일을 삭제했습니다. 복구할 방법이 없어서 그러는데 혹시 git 리파지토리 소스나, 아니면 교육용 백업본이라도 있으면 주실 수 있을까요?
미해결
실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
안녕하세요. 강의 내용 중 정확히 이해하지 못하고 있는 것이 있어서 질문 드립니다. 강의 중 로그인 버튼 같이 간단한 동작만 있는 컴포넌트는 그 자체를 테스트 하는 것이 아니라, 통합 테스트로 상태에 따른 동작을 검증하는 것이 더 효율적이고 정확한 테스트가 된다. 라고 하셨습니다. 또한 이런 컴포넌트는 스토리북과 같은 도구를 사용하여 스타일이나 레이아우싱 틀어지지 않는지 확인하는 것이 더 중요하다. 라고 말씀 하셨습니다. 이 뜻은 통합 테스트를 스토리북과 같은 도구와 함께 하라는 것이 아니라, 통합 테스트로 상태에 따른 동작을 검증하고, 그 안에 있는 각각의 컴포넌트들은 스토리북 안에서 스타일과 레이아웃이 틀어지지 않는지 확인하라는 것일까요? 아니면 스토리북을 통해 네비게이션 같은 컴포넌트를 만들고 그 단위로 통합 테스트를 하란 말씀이실까요?? 궁금합니다. 강의 너무 잘 듣고 있습니다. 정말 감사합니다!
해결됨
Vue.js 끝장내기 - 실무에 필요한 모든 것
안녕하세요. 5_styling 브랜치를 받고 2개의 에러를 수정이후 메인페이지 이동을 위한 this.$router.push('/main') ; 코드를 입력하면 아래와 같은 의존성 문제가 발생합니다.어떻게 해야 할까요?routers/index.js 에는 .. 아래 코드 추가해 주었습니다. { path: '/main', component: () => import('@/views/MainPage.vue'), },
미해결
Next + React Query로 SNS 서비스 만들기
안녕하세요 선생님 강의보면서 플젝을 만들다가 여쭤보고 싶은게 생겼습니다. 📦(afterLogin) ┣ 📂(home) ┃ ┗ 📂_component ┃ ┃ ┣ 📜mbtiCarousel.module.css ┃ ┃ ┗ 📜MbtiCarousel.tsx ┣ 📂@modal ┃ ┣ 📂(.)promise ┃ ┃ ┗ 📂form ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┣ 📂[userId] ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┗ 📜UsrCarousel.tsx ┃ ┃ ┗ 📜page.tsx ┃ ┗ 📜default.tsx ┣ 📂like ┃ ┗ 📜page.tsx ┣ 📂messages ┃ ┗ 📜page.tsx ┣ 📂profile ┃ ┗ 📜page.tsx ┣ 📂promise ┃ ┣ 📂form ┃ ┃ ┗ 📜page.tsx ┃ ┣ 📂_component ┃ ┃ ┣ 📜PromiseFormButton.tsx ┃ ┃ ┣ 📜promiseSection.module.css ┃ ┃ ┗ 📜PromiseSection.tsx ┃ ┗ 📜page.tsx ┣ 📂recommend ┃ ┣ 📂_component ┃ ┃ ┗ 📜RecommendSection.tsx ┃ ┣ 📜page.tsx ┃ ┗ 📜recommend.module.css ┣ 📂setting ┃ ┗ 📜page.tsx ┣ 📂[userId] ┃ ┗ 📜page.tsx ┣ 📂_component ┃ ┣ 📜Back.tsx ┃ ┣ 📜FriendRecommendSection.tsx ┃ ┣ 📜MainTitle.tsx ┃ ┣ 📜MbtiRecommendSection.tsx ┃ ┣ 📜Modal.tsx ┃ ┣ 📜userCard.module.css ┃ ┣ 📜UserCard.tsx ┃ ┗ 📜UserCardArticle.tsx ┣ 📜layout.module.css ┣ 📜layout.tsx ┗ 📜page.tsx 이런구조에서 (afterLogin) > UserCard 를 클릭하면 @modal > [userId] > page.tsx가 모달창으로 뜨게 됩니다. 새로고침해도 모달창이 뜨게 되어있습니다. 이게 로컬에서는 잘 작동하는데 테스트하려고 vercel에 배포해서 확인했더니 url은 바뀌는데 새로고침이 되고 화면은 바뀌지 않더라구요. 구글링해도 만족스런 답변이 없어서 이렇게 글을 남깁니다. return ( // <UserCardArticle user={user}> <Card className={style.userCard}> <Link href={`/${user.id}`} scroll={false} className='w-full h-full absolute top-0 left-0'> <img src={user.image[0]} className='rounded-xl h-full block w-full' alt="img" /> <div className={style.userInfo}> <h2 className='text-white font-extrabold text-xl'>{user.mbti.mbti}, 궁합 {user.mbti.score}%</h2> <h2 className='text-white font-extrabold text-xl'>{user.nickname}, {user.age}</h2> <p className='text-white font-semibold text-base'>{user.distance}km, {user.area}</p> </div> </Link> <div className='absolute bottom-3 px-3 w-full'> <Button variant={'default'} className='bg-white hover:bg-slate-50 w-full'> <UserPlus color='#000000' /> <span className='ml-2 text-black font-extrabold'>친구신청</span> </Button> </div> </Card> // </UserCardArticle> ) 기존 선생님처럼 UserCardArticle이란 컴포넌트를 만들어서 router.push도 해봤다가 link태그로 고쳐봤는데도 새로고침이 되어서 어떤부분을 봐야할지 조언 듣고 싶습니다. 감사합니다.
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
설치가 잘못된 걸까요.. yarn dev하니 오류가 납니다ㅜ
해결됨
[웹 개발 풀스택 코스] 순수 자바스크립트 기초에서 실무까지
sort()함수 부분에 대해서 헷갈리는 부분이 있어서 질문드려요! 질문1. 인자 a, 인자b의 순서가 다름 제가 알고 있기로는 인자 a - 100, b - 40 으로 알고 있습니다 강사님이 설명하신것은 인자 a - 40, 인자 b - 100입니다. console.log 출력 결과는 a - 100, b - 40 으로 강사님 설명과 반대로 나와서 제가 출력시 실수한 부분이 있는지 질문드립니다 질문2. 양수일때 자리가 바뀐다 질문1. 에서 인자 a - 100, b - 40 이 맞다면 음수일때 자리가 바뀌는게 맞지 않나요?? 바쁘시겠지만 답변부탁드립니다!
미해결
Next + React Query로 SNS 서비스 만들기
지금 로그인 후 핸들러에서 값을 잘 주는것을 확인했고 auth.ts의 콘솔 부분에 값이 잘 나오는것을 확인했습니다 여기서 result에서도 성공했다고 나오는데 replace가 안되네요 이유가 뭘까요
미해결
[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
안녕하세요. 강의: NestJS REST API 백엔드 완전 정복 섹션: 35 모듈 네스팅 동영상: Paginate Comments API 만들기 위에 적은 강의 동영상의 끝부분이, 의도치 않게 잘린 것 같습니다. 마지막인 5:56 시간에서, 말씀하는 도중에 강의가 끝나버립니다. 확인해 주시면 감사하겠습니다.
미해결
웹 애니메이션의 새로운 표준, Web Animations API
안녕하세요. 강의 정말 재밌게 보았습니다 :) 강의를 듣고 Vue2에 적용하려 하니 해당 에러가 발생합니다. js를 import해서 사용하는 것 만으로는 제약이 있는 것인가요..? 😥 😥
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
안녕하세요! 강의 잘 듣고 있습니다! 이번 과제 코드 피드백 부탁드립니다! 고맙습니다. <화면> <html> <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>SignUp</title> <link rel="stylesheet" href="./final.css"> <script defer src="./final.js"></script> </head> <body> <div class="wrapper"> <div class="wrapper__header"> <span id="header__title">코드캠프 회원가입</span> </div> <div class="wrapper__body"> <div class="wrapper__text"> <input type="text" id="email" placeholder="이메일을 입력해 주세요."> <span class="errorMsg email">이메일이 올바르지 않습니다.</span> <input type="text" id="name" placeholder="이름을 입력해 주세요."> <span class="errorMsg name">이름이 올바르지 않습니다.</span> <input type="text" id="pw1" placeholder="비밀번호를 입력해 주세요."> <span class="errorMsg pw1">비밀번호를 입력해주세요.</span> <input type="text" id="pw2" placeholder="비밀번호를 다시 입력해 주세요."> <span class="errorMsg pw2">비밀번호를 입력해주세요.</span> </div> <div class="wrapper__phone" oninput="phone()"> <input type="text" id="num1" maxlength="3"> - <input type="text" id="num2" maxlength="4"> - <input type="text" id="num3" maxlength="4"> </div> <div class="wrapper__certification"> <div class="cert__number"> <span id="certNum">000000</span> <button class="chkBtn" disabled="true">인증번호 전송</button> </div> <div class="cert__time"> <span id="certTimer">3:00</span> <button class="chkBtn" disabled="true">인증완료</button> </div> </div> <div class="wrapper__select"> <div class="select__locale"> <select id="locale"> <option selected disabled>지역을 선택하세요</option> <option value="서울">서울</option> <option value="경기">경기</option> <option value="인천">인천</option> </select> <span class="errorMsg locale">지역을 선택해주세요.</span> </div> <div class="select__gender"> <label for="woman"> <input type="radio" name="gender" id="woman"> 여성 </label> <label for="man"> <input type="radio" name="gender" id="man"> 남성 </label> </div> <span class="errorMsg gender">성별을 선택해주세요.</span> </div> </div> <div class="divideLine"></div> <div class="wrapper__check"> <!-- <button class="submit" disabled="true">가입하기</button> --> <button class="submit">가입하기</button> </div> </div> </body> </html> <css> *{ box-sizing: border-box; margin: 0; } html, body{ width: 540px; } .chkBtn{ width: 120px; height: 40px; border: 1px solid #D2D2D2; border-radius: 7px; font-size: 16px; font-weight: 400; color: #0068FF; background-color: #FFF; cursor: pointer; } .chkBtn.active { width: 120px; height: 40px; border: 1px solid #D2D2D2; border-radius: 7px; font-size: 16px; font-weight: 400; background-color: #0068FF; color: #FFF; cursor: pointer; } .errorMsg{ width: 100%; color: red; font-size: 10px; display: flex; flex-direction: column; align-items: center; visibility: hidden; } .wrapper{ width: 100%; height: 100%; padding: 60px 80px; border: 1px solid #AACDFF; border-radius: 20px; box-shadow: 7px 7px 39px rgba(0, 104, 255, .25); } .wrapper__header{ width: 100%; font-size: 32px; font-weight: 700; color: #0068FF; padding-bottom: 60px; } .wrapper__body{ width: 100%; } .wrapper__text > input{ width: 100%; height: 60px; margin-top: 20px; font-size: 16px; font-weight: 400; border: 1px solid #D2D2D2; border-radius: 7px; padding: 18px; } .wrapper__phone{ width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 20px 0; } .wrapper__phone > input{ width: 100px; height: 40px; border: 1px solid #D2D2D2; border-radius: 7px; } .wrapper__certification { width: 100%; display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; } #certNum, #certTimer{ color: #0068FF; font-size: 18px; padding-right: 20px; } .cert__time{ padding: 20px 0; } .wrapper__select{ width: 100%; display: flex; flex-direction: column; align-items: center; } .select__locale{ width: 100%; display: flex; flex-direction: column; justify-content: center; } #locale{ width: 100%; height: 60px; border: 1px solid #D2D2D2; border-radius: 7px; color: #797979; font-size: 16px; font-weight: 400; padding: 18px; } .select__gender{ width: 140px; display: flex; justify-content: space-between; padding-top: 30px; } .divideLine{ width: 100%; border: 1px solid #E6E6E6; margin: 20px 0; } .wrapper__check{ width: 100%; display: flex; justify-content: center; } .submit { width: 100%; height: 60px; font-size: 18px; font-weight: 400; color: #0068FF; background-color: #FFF; border: 1px solid #0068FF; border-radius: 7px; } <js> const submit = document.querySelector('.submit'); // 가입하기 const numberChk = document.querySelector('.cert__number .chkBtn'); // 인증번호 전송 const timeChk = document.querySelector('.cert__time .chkBtn'); // 인증완료 let time = 180; // 180초, 인증 시간 let isStarted = false; // email const emailChk = () => { let email = document.getElementById('email').value; if(email.includes('@') === true){ let isEmail = email.split('@')[1].includes('.'); if(isEmail === false){ document.querySelector('.errorMsg.email').style.visibility = 'visible'; document.querySelector('.errorMsg.email').value = ''; return false; } else { document.querySelector('.errorMsg.email').style.visibility = 'hidden'; return true; } } else { document.querySelector('.errorMsg.email').style.visibility = 'visible'; document.getElementById('email').value = ''; return false; } } // name const nameChk = () => { let name = document.getElementById('name').value; if(name.length === 0){ document.querySelector('.errorMsg.name').style.visibility = 'visible'; return false; } else { document.querySelector('.errorMsg.name').style.visibility = 'hidden'; return true; } } // pw const pwChk = () => { let pw1 = document.getElementById('pw1').value; let pw2 = document.getElementById('pw2').value; if(pw1 && pw2){ if(pw1 === pw2){ document.querySelector('.errorMsg.pw1').style.visibility = 'hidden'; document.querySelector('.errorMsg.pw2').style.visibility = 'hidden'; return true; } else { document.querySelector('.errorMsg.pw1').style.visibility = 'visible'; document.querySelector('.errorMsg.pw2').style.visibility = 'visible'; document.querySelector('.errorMsg.pw1').innerHTML = '비밀번호가 일치하지 않습니다.' document.querySelector('.errorMsg.pw2').innerHTML = '비밀번호가 일치하지 않습니다.' return false; } } else { document.querySelector('.errorMsg.pw1').style.visibility = 'visible'; document.querySelector('.errorMsg.pw2').style.visibility = 'visible'; return false; } } // phone const phone = () => { let num1 = document.getElementById('num1').value; let num2 = document.getElementById('num2').value; let num3 = document.getElementById('num3').value; if(num1.length === 3) { document.getElementById('num2').focus(); if(num2.length === 4) { document.getElementById('num3').focus(); } } if(num1.length === 3 && num2.length === 4 && num3.length === 4){ numberChk.classList.add('active'); certification(); } } const certification = () => { // 인증번호 numberChk.disabled = false; numberChk.addEventListener('click', e => { let randomNumber = String(Math.trunc(Math.random() * 1000000)).padStart(6, '0') document.getElementById('certNum').innerText = randomNumber; // 타이머 if(isStarted === false){ isStarted = true; timeChk.disabled = false; let timer = setInterval(() => { if(time >= 0){ let min = Math.trunc(time / 60); let sec = String(time % 60).padStart(2,'0'); document.getElementById('certTimer').innerText = `${min}:${sec}`; time--; } else { clearTime(timer); } }, 100) timeChk.addEventListener('click', e => { if(time >= 0){ alert('인증이 완료 되었습니다.'); clearTime(timer); submit.disabled = false; } }) } }) } const clearTime = (timer) => { timeChk.classList.remove('active'); numberChk.classList.remove('active'); document.getElementById('certNum').innerText = '000000'; document.getElementById('certTimer').innerText = '0:00'; timeChk.disabled = true; numberChk.disabled = true; isStarted = false; clearInterval(timer); } const checkValidation = () => { emailChk(); nameChk(); pwChk(); if(emailChk() && nameChk() && pwChk()) { return true; } else { return false; } } // 검증 submit.addEventListener('click', e => { checkValidation(); if(checkValidation()){ alert('코드캠프 가입을 축하합니다.'); } });
해결됨
[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
자바스크립트 함수가 조금 어려운데 함수는 그냥 관련된 코드들을 작성할 때 사용하나요? 예를 들어 input으로 어떠한걸 한다면 input 함수를 만들어서 이 함수안에는 input과 관련된 코드들을 작성한다고 보면되는건가요?
미해결
Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
안녕하세요! 강의 듣으며 코드 작성중에 있는데 vuex로 코드를 작성하게 되면서 props데이터를 삭제하고 store.js로 mutation로 app.js에 있는 methodsf를 옮기게 되면서 새로고침해야지만 리스트가 추가/삭제되는 현상이 나타나고 있습니다. 다시 삭제했다가 작업해도 마찬가지네요.. 코드양이 너무 방대해서 올리기는 어려울것 같고 혹시 버전차이에 문제일수도 있나요? vue devtools에는 실시간으로 나타나는걸로 보입니다...
해결됨
한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
안녕하세요. 선생님 강의에 따라서 투두 리스트까지 완강하였는데요. 복습시 이번에 만들어본 프로젝트를 보지 않고 만들 수 있을 때까지 연습해보는 식으로 나아가면 될까요??
미해결
Next + React Query로 SNS 서비스 만들기
modal이 없는 상황의 오류를 해결하기위해 제로초님이 default.tsx라는 파일을 소개해줬는데요, 그냥 layout.tsx에서 애초에 Probs를 정의할때 type Probs= modal?:reactNode로 하면 안될까요?
미해결
웹디자인기능사 자격증 대비(2023년 출제기준 반영버전)
초반에 제이쿼리 소스를 넣을때 둘 중 하나만 언더바가 생겨요 ㅠㅠ