개발하는 루루언니

react 이메일 양식 폼 + 유효성 검사 본문

컴퓨터 정보/리액트

react 이메일 양식 폼 + 유효성 검사

혜닝혜루 2023. 7. 3. 13:10
728x90
반응형

 

1. 리액트 부트스트랩 설치하기 *

npm install react-bootstrap bootstrap

 

2. 전체코드

 const [userId, setUserId] = useState("");
    const [email, setEmail] = useState("");
    const [phoneNumber, setPhoneNumber] = useState("");
    const [emailList,setEmailList] = useState({});

    const [userIdError, setUserIdError] = useState(false);
    const [emailError, setEmailError] = useState(false);
    const [phoneNumberError,setphoneNumberError] = useState(false);


    const handleChange = (e) => {
        const { name, value } = e.target;
        if(name == 'name'){
            const userIdRegex =  /^[가-힣]{2,4}|[a-zA-Z]{2,10}\s[a-zA-Z]{2,10}$/;
            if ((!value || (userIdRegex.test(e.target.value)))) setUserIdError(false);
            else setUserIdError(true);
            setUserId(e.target.value)
        }
        if(name == 'email') {
            const emailRegex = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;
            if (!e.target.value || emailRegex.test(e.target.value)) setEmailError(false);
            else setEmailError(true);
            setEmail(e.target.value)
        }
        if(name == 'phonNumber') {
            var regExp = /^\d{2,3}-\d{3,4}-\d{4}$/;
            if (!e.target.value || regExp.test(e.target.value)) setphoneNumberError(false);
            else setphoneNumberError(true);
            setPhoneNumber(e.target.value);
        }
        setEmailList((emailList)=> ({...emailList, [name] : value}))
        console.log("handleChange", emailList);
    }


    const validation = () => {
        if(!userId) setUserIdError(true);
        if(!email) setEmailError(true);
        if(!phoneNumber) setphoneNumberError(true);
    }
    useEffect(()=>{
        onSubmit()
    },[])

    const onSubmit = async (e) => {
        e.preventDefault();
        alert("견적서 보내기 완료")
        const result = await quotelnquirypage.postEmail
        if(validation()) return;
        
        // API Call
    }
    const [checkValue, setCheckValue] = useState('사용');

    const checkOnlyOne = (e) => {
        let checkItem = document.getElementsByName('useType');
        Array.prototype.forEach.call(checkItem, function (el){
            el.checked = false;
        });
        e.target.checked = true;
        setCheckValue(e.target.defaultValue);
        };
    return (
    <>
    <div>       
            <div>
                <label id='use'>신청함</label>
                <input type='radio' value='사용' id='use'  onChange={(e)=> checkOnlyOne(e)} checked={checkValue === '사용'}></input>
                <label id='use'>신청안함</label>
                <input type='radio' id='use' value='사용안함' onChange={(e)=> checkOnlyOne(e)} checked={checkValue === '사용안함'}></input>
            </div>
            <Container className="panel">
                <Form>
                    <Form.Group as={Row} className="mb-3">
                        <Col sm>
                            <Form.Control maxLength={20} name="name" value={userId} placeholder="User Name" required onChange={(e)=>handleChange(e)} />
                            {userIdError && <div style={{color:'red'}} className="invalid-input">한글/영문명 으로 작성해 주세요.</div>}
                        </Col>
                    </Form.Group>
            
                    <Form.Group as={Row} className="mb-3">
                        <Col sm>
                            <Form.Control maxLength={50} type="input" name="email" value={email} required placeholder="Email Address" onChange={(e)=>handleChange(e)} />
                            {emailError && <div style={{color:'red'}} className="invalid-input">올바른 전자 메일 형식을 입력하십시오.</div>}
                        </Col>
                    </Form.Group>
                    <Form.Group as={Row} className="mb-3">
                        <Col sm>
                            {checkValue == '사용' ? 
                            <Form.Control maxLength={50} type="input" name="phonNumber" required placeholder="phonNumber"   onChange={(e)=>handleChange(e)} />
                            : <Form.Control maxLength={50} type="input" placeholder="phonNumber" disabled value={phoneNumber} onChange={(e)=>handleChange(e)} />}
                            
                            {phoneNumberError && checkValue == '사용' && <div style={{color:'red'}} className="invalid-input">올바른 phoneNumber 형식을 입력하십시오. 예시) 010-1111-2222</div>}
                        </Col>
                    </Form.Group>
                    <Form.Group as={Row} className="mb-3">
                        <Col sm>
                            <Form.Control maxLength={50} name="title" type="input"required placeholder="title"  onChange={(e)=>handleChange(e)} />
                        </Col>
                    </Form.Group>
                    <Form.Group className="mb-3" controlId="exampleForm.ControlTextarea1">
                    <Form.Label>Example textarea</Form.Label>
                    <Form.Control as="textarea" name="content" onChange={(e)=>handleChange(e)} rows={3} />
                    </Form.Group>
                    <br />
                    <div className="d-grid gap-1">
                        <Button variant="secondary" onClick={(e)=>onSubmit(e)}>
                            견적서 요청하기
                        </Button>
                    </div>
                </Form>
                <br />
                <span className="text">Have an account? <Link to="/login" className="link">Sign In</Link></span>
            </Container>
        </div>
    </>
        )
    }

 

★ 견적서를 작성후 이메일을 보내는 코드를 작성하였다 ( 백엔드 쪽은 작성하지 못하였음 )

 

🌈  구현하고 싶은 로직 

1.  이름 ( 유효성 검사 : 한글/영문 명으로 작성이 되어야함 안될시 빨간 글씨로 작성요구 )

2. 이메일 ( 유효성 검사: @naver.com , net 등등 이메일 형식으로 작성 해야함 안그러면 빨간 글씨로 작성 요구)

3. 전화번호 ( 유효성 검사 : 앞엔 2,3 가운데는 3,4자리 맨마지막은 4자리 )  전화번호 사이에는  ' - ' 을 넣어야함

4. 제목 

5. 내용

6. 견적서 요청 버튼 ( 버튼을 누르면 form이 전송된다 -> 백엔드랑 연동 해야해서 구현 X 코드만 작성)

 

7. 상담 요청 전화 신청과 신청안함 라디오 버튼이 있다. 요청을 누르면 전화번호 입력 인풋 창은 작성이 가능하고

신청안함 라디오 버튼을 클릭하면 전화번호 입력 인풋 박스가 비활성화가 된다.

 


📕 코드를 짠 순서 

1. html 부터 우선 작성을 하자  ( 리액트 부트스트랩을 통해 npm 설치 후 폼을 가져왔다 )

2. 폼에 입력한 값을 담을 useState 를 생성한다.

    const [emailList,setEmailList] = useState({});

3. input 값에 텍스트를 작성할 때 마다 값을 담아주기 위해 onChange 를  input 값마다 넣어준다.

4. handleChange 라는 함수를 만들어 onChage 에 연동을 해주고 event 값을 넘겨준다.

5. e.target 을 받아서 name 과 value값을 꺼내준다.

 const handleChange = (e) => {
        const { name, value } = e.target;
        if(name == 'name'){
            const userIdRegex =  /^[가-힣]{2,4}|[a-zA-Z]{2,10}\s[a-zA-Z]{2,10}$/;
            if ((!value || (userIdRegex.test(e.target.value)))) setUserIdError(false);
            else setUserIdError(true);
            setUserId(e.target.value)
        }
        if(name == 'email') {
            const emailRegex = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;
            if (!e.target.value || emailRegex.test(e.target.value)) setEmailError(false);
            else setEmailError(true);
            setEmail(e.target.value)
        }
        if(name == 'phonNumber') {
            var regExp = /^\d{2,3}-\d{3,4}-\d{4}$/;
            if (!e.target.value || regExp.test(e.target.value)) setphoneNumberError(false);
            else setphoneNumberError(true);
            setPhoneNumber(e.target.value);
        }
        setEmailList((emailList)=> ({...emailList, [name] : value}))
        console.log("handleChange", emailList);
    }

 

 

6. 꺼내준 name 을 이용하여 유효성 검사를 할 것인데. 조건문을 사용하여 if( name == 'name' ) 일시 유효성을 검사할 코드를 안에 작성 해준다.  

 

7. 각 이름, 이메일,번호 에 대한 유효성 검사 코드를 작성한 후 조건문을 걸어 value의 값이 없거나 즉, 인풋창에 값을 입력하지 않았거나  유효성 검사를 했을때 맞는 경우에는 setUserIdError 가 기본값인 false 로 유지된다.

 

8. 그반대로 입력하고나서 유효성 검사를 했을때 틀린경우 setUserIdError 를 true로 변환을 해주게 되면? 

 

 <Form.Group as={Row} className="mb-3">
                        <Col sm>
                            <Form.Control maxLength={20} name="name" value={userId} placeholder="User Name" required onChange={(e)=>handleChange(e)} />
                            {userIdError && <div style={{color:'red'}} className="invalid-input">한글/영문명 으로 작성해 주세요.</div>}
                        </Col>
                    </Form.Group>

  이렇게 UserIdError 가 && 즉, true인 경우  한글/영문 명으로 작성하라는 빨간 text 를 출력 해주게 된다.


 

📒 이메일을 담은 값을 넘겨줄때 axios를 이용 하였다.

 

sevice 라는 폴더를 만든 후 - emailListService.js 라는 파일을 만들었다.

import axios from "axios";
import React from 'react'


export const onGetMyEmail = async () => {
  const response = await axios.get('/백엔드에서 알려주는 url 입력하기 ');
  return response.data;
}

export const postEmail = async (emailList) => {
  const responsePost = await axios.post(
    `/백엔드에서 알려주는 url 입력하기 `,
    {
      name : emailList.name,
      email : emailList.email,
      phonNumber : emailList.phonNumber,
      title : emailList.title,
      content : emailList.content,
    }
  )
  return responsePost.data;
}

const EmailListService = {onGetMyEmail,postEmail};

export default EmailListService;

 

 

1.  onGetMyEmail 에서 axios.get 을 사용했기 때문에 내가 전송한 이메일을 불러오는 역할을 하게 된다.

 

2. postEmail 은 파라미터로 emailList를 받아오게 되는데 그 내용은 위에서 input에 onChange 를 줘서 받은 값들을 넘기면서 받아오게 된다.

 

그 내용을 백엔드쪽에 보내고 결과값을 받아오게 되면 그 데이터가 백엔드쪽에 저장이 된다.

responsePost.data를 보면 그 내용이 return 되어 값을 받아볼 수 있따.

 

728x90