개발자
로그인 창을 만들고 있는데요 id인풋칸에서 엔터를 눌렀을때 pw칸으로 또 엔터를 눌렀을때 로그인 함수를 실행시키려 합니다 하지만 id 인풋칸에서 엔터를 누를시 로그인 함수가 실행됩니다. id칸에서 글자를 입력후 다시 id칸을 마우스로 터치해야 먹히더라고요 왜인지 코드 한번만 봐주세요 제발 부탁드립니다
1import Head from 'next/head'
2import styles from '@/styles/Login.module.css'
3import Link from "next/link";
4import {useRef, useState} from "react";
5import axios from "axios";
6import {toast, ToastContainer} from "react-toastify"
7import "react-toastify/dist/ReactToastify.css"
8
9export default function Login() {
10 const [id, setId] = useState('')
11
12 const [pw, setPw] = useState('')
13
14 const inputRef = useRef<HTMLInputElement>(null)
15
16 const login = () => {
17 inputRef.current?.blur()
18 axios.post('/api/login', {
19 id: id,
20 pw: pw
21 }).then((res) => {
22 if (!res.data.success) return;
23 window.location.href = '/'
24 }).catch((err) => {
25 if (err.response.data.message) {
26 toast.error(err.response.data.message);
27 } else {
28 toast.error('서버에 오류가 발생했습니다.');
29 }
30 })
31 setId('')
32 setPw('')
33 }
34
35 return (
36 <>
37 <Head>
38 <meta name="viewport" content="width=device-width, initial-scale=1"/>
39 <link rel="icon" href="/favicon.ico"/>
40 <title>문시장 - 문학을 시작하는 장소</title>
41 <meta property="og:title" content="문시장!"/>
42 <meta property="og:description" content="다양한 문학을 접하고 시작하는 장소!"/>
43 <meta property="og:image" content="/background.png"/>
44 <meta property="og:type" content="website"/>
45 <meta property="og:site_name" content="문시장"/>
46 <meta property="og:locale" content="ko_KR"/>
47 </Head>
48
49 <main>
50 <div className={styles.background}>
51 <ToastContainer
52 position="top-right"
53 autoClose={1000}
54 />
55 <div className={styles.card}>
56 <div className={styles.flex_left}>
57 <Link className={`${styles.back} ${styles.flex_left}`} href={'/'}>◀ 뒤로가기</Link>
58 <Link className={`${styles.back} ${styles.flex_right}`} href={'/register'}>회원가입 ▶</Link>
59 </div>
60 <div className={styles.padding}>
61 <div className={styles.flex_center}>
62 <h1 className={styles.title}>문시장</h1>
63 </div>
64
65 <div className={styles.flex_column_center}>
66 <h1 className={styles.input_message}>아이디</h1>
67 <input className={`${styles.input}`}
68 onChange={(e) => setId(e.target.value)}
69 value={id}
70 onKeyDown={(e) => {
71 e.preventDefault();
72 if (e.key === 'Enter') {
73 inputRef.current?.focus()
74 }
75 }}
76 />
77 </div>
78
79 <div className={styles.flex_column_center}>
80 <h1 className={styles.input_message}>비밀번호</h1>
81 <input className={`${styles.input}`}
82 ref={inputRef}
83 onChange={(e) => setPw(e.target.value)}
84 value={pw}
85 onKeyDown={(e) => {
86 e.preventDefault();
87 if (e.key === 'Enter') {
88 login()
89 }
90 }}
91 />
92 </div>
93
94 <div className={styles.flex_column_center}>
95 <button className={styles.button}
96 onClick={() => {
97 login()
98 }}
99 >로그인
100 </button>
101 </div>
102 </div>
103 </div>
104 </div>
105 </main>
106 </>
107 )
108}
답변 4
조용구
Senior Front-end Engineer • 2023년 07월 18일
헛 그렇군여 ㅠㅠ 이렇게 했을때 아이디 입력 박스에서 엔터하면 비밀번호 입력 박스로 이동되는데, 확인 부탁드립니다 :) https://jsfiddle.net/ykb12vrh/3/
민규
작성자
코리아it아카데미 웹 • 2023년 07월 18일
해당사이트도 똑같은 증상이 일어나네요 ㅠㅠ
민규
작성자
코리아it아카데미 웹 • 2023년 07월 18일
다른분 의견을 따라 한글 영어 체크를 해봤는데 한글만 일어나는 증상이네요 한글로 했을때도 정상작동되게 하는방법 없을까요
조용구
Senior Front-end Engineer • 2023년 07월 18일
아마도 제 데스크톱이랑 환경이 다른가보군여 ㅠㅠ 한글 이슈라면 onChange를 onInput으로 바꿔서 테스트 해보실래여?? 이것 말고는 떠오르는게 없네여
엔터키를 연동하는 대신에 form 태그 사용을 제안드립니다. `<form>` 태그를 사용하면 엔터키를 눌렀는지 감지할 필요가 없으며, 로그인과 같이 사용자가 입력한 양식을 서버에 제출하는 상황에서 웹 표준으로 권장되는 방식입니다. 요구사항을 코드로 옮길 때는 W3C에서 합의한 웹표준을 지키며 코드를 구현하도록 작성하는 것이 좋습니다. 첨부한 코드는 작성하신 코드를 `form` 기반으로 변경한 코드입니다.
1import Head from 'next/head'
2import styles from '@/styles/Login.module.css'
3import Link from "next/link";
4import {useRef, useState} from "react";
5import axios from "axios";
6import {toast, ToastContainer} from "react-toastify"
7import "react-toastify/dist/ReactToastify.css"
8
9export default function Login() {
10 const [id, setId] = useState('')
11 const [pw, setPw] = useState('')
12
13 const inputRef = useRef<HTMLInputElement>(null)
14
15 const handleLogin = (event) => {
16 event.preventDefault();
17 inputRef.current?.blur()
18 axios.post('/api/login', {
19 id: id,
20 pw: pw
21 }).then((res) => {
22 if (!res.data.success) return;
23 window.location.href = '/'
24 }).catch((err) => {
25 if (err.response.data.message) {
26 toast.error(err.response.data.message);
27 } else {
28 toast.error('서버에 오류가 발생했습니다.');
29 }
30 })
31 setId('')
32 setPw('')
33 }
34
35 return (
36 <>
37 <Head>
38 <meta name="viewport" content="width=device-width, initial-scale=1"/>
39 <link rel="icon" href="/favicon.ico"/>
40 <title>문시장 - 문학을 시작하는 장소</title>
41 <meta property="og:title" content="문시장!"/>
42 <meta property="og:description" content="다양한 문학을 접하고 시작하는 장소!"/>
43 <meta property="og:image" content="/background.png"/>
44 <meta property="og:type" content="website"/>
45 <meta property="og:site_name" content="문시장"/>
46 <meta property="og:locale" content="ko_KR"/>
47 </Head>
48
49 <main>
50 <div className={styles.background}>
51 <ToastContainer
52 position="top-right"
53 autoClose={1000}
54 />
55 <div className={styles.card}>
56 <div className={styles.flex_left}>
57 <Link className={`${styles.back} ${styles.flex_left}`} href={'/'}>◀ 뒤로가기</Link>
58 <Link className={`${styles.back} ${styles.flex_right}`} href={'/register'}>회원가입 ▶</Link>
59 </div>
60 <form onSubmit={handleLogin} className={styles.padding}>
61 <div className={styles.flex_center}>
62 <h1 className={styles.title}>문시장</h1>
63 </div>
64
65 <div className={styles.flex_column_center}>
66 <h1 className={styles.input_message}>아이디</h1>
67 <input className={`${styles.input}`}
68 onChange={(e) => setId(e.target.value)}
69 value={id}
70 />
71 </div>
72
73 <div className={styles.flex_column_center}>
74 <h1 className={styles.input_message}>비밀번호</h1>
75 <input className={`${styles.input}`}
76 ref={inputRef}
77 onChange={(e) => setPw(e.target.value)}
78 value={pw}
79 />
80 </div>
81
82 <div className={styles.flex_column_center}>
83 <button className={styles.button}
84 type="submit"
85 >로그인
86 </button>
87 </div>
88 </form>
89 </div>
90 </div>
91 </main>
92 </>
93 )
94}
민규
작성자
코리아it아카데미 웹 • 2023년 07월 18일
해당코드로 하면 패스워드칸에서 엔터시 보내기가 안되지 않나요 네이버처럼 엔터시 보내기 같은 기능을 하고싶어서요
최승윤
모션원 프론트엔드 개발자 • 2023년 07월 19일
<form>을 쓰면 자동으로 엔터키 감지가 됩니다.
삭제된 사용자
2023년 07월 18일
혹시 id 값으로 한글 사용하실까요?
민규
작성자
코리아it아카데미 웹 • 2023년 07월 18일
네 한글로 사용중입니다 영어로 해보니깐 잘되네요 ;ㅅ; 한글했을때도 똑같이 하고싶은데 방법이 없을까요
문제가 발생하는 이유는 `id` 인풋칸에서 엔터를 눌렀을 때 `inputRef.current?.focus()`를 호출하여 다시 `id` 인풋칸에 포커스를 맞추기 때문입니다. 이로 인해 `id` 인풋칸에 다시 엔터를 눌러도 로그인 함수가 실행되지 않고 포커스만 다시 맞춰지게 됩니다. 해결하기 위해서는 `id` 인풋칸에서 엔터를 눌렀을 때 다음 인풋칸인 `pw` 인풋칸으로 포커스를 이동하고, `pw` 인풋칸에서 엔터를 눌렀을 때 로그인 함수를 실행하도록 수정해야 합니다. 이를 위해 다음과 같이 코드를 수정할 수 있습니다: 아래와 같이 수정하면 `id` 인풋칸에서 엔터를 누르면 `pw` 인풋칸으로 포커스가 이동하고, `pw` 인풋칸에서 엔터를 누르면 로그인 함수가 실행됩니다. 주의할 점은 `e.preventDefault()`를 사용하여 엔터 키의 기본 동작인 폼 제출을 막아야 한다는 것입니다. 이를 통해 엔터 키를 눌렀을 때 원치 않는 동작이 발생하는 것을 방지할 수 있습니다.
1<input className={`${styles.input}`}
2 onChange={(e) => setId(e.target.value)}
3 value={id}
4 onKeyDown={(e) => {
5 if (e.key === 'Enter') {
6 e.preventDefault();
7 inputRef.current?.focus(); // pw 인풋칸으로 포커스 이동
8 }
9 }}
10/>
11
12<input className={`${styles.input}`}
13 ref={inputRef}
14 onChange={(e) => setPw(e.target.value)}
15 value={pw}
16 onKeyDown={(e) => {
17 if (e.key === 'Enter') {
18 e.preventDefault();
19 login(); // 로그인 함수 실행
20 }
21 }}
22/>
커리어리 AI 봇의 답변을 평가해 주세요!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!