[ react ] 입력한 데이터 MYSQL 로 전달하기 (feat. form tag)

Suji Kang·2023년 9월 26일
0
post-thumbnail

🐾 버튼이 클릭되었을때 실직적으로 데이터가 전달이 되어야한다.

1. form 태그의요청방식을 이해해야한다.

📌 일단, mysql table 을 먼저 만들어보자❗️

CREATE TABLE tbl_users(
   email varchar(30) primary key,
    pw varchar(200) not null,
    question int not null check (question IN(1, 2, 3)),
    answer varchar(200) not null,
    created_date datetime default now() not null,
    updated_date datetime default now() not null,
    profile_url varchar(200) default '/profile.jpg',
   cover_url varchar(200) default '/cover.jpg'
);

값을 입력하고 button을 click하면 4개의 값을 mysql 에 넣어줘야한다. 그걸 넣어주는것은 누가 해준다

express 서버가.

app.js


//회원 한명 추가
app.post('/api/users', (req, res) => {
    console.log('req.body', req.body);
  //req에 body 안에 다 넣어놨다
    res.json('포스트요청에 대한 응답완료!');
});

🔎 이것은 전통적인 방식이다🤨

form 안에는 속성으로 methodaction 이 있다.

action = 누구한테
method = 어떤방식으로
전송이된다.

📝 전송은 어떻게 받지그럼

👉 body안에 넣어서준다
req.body 👉 req안body 값들을 받는다.

📌 여기서 그냥 console.log('req.body', req.body); 하면, 결과값은 ❓
🌟 undefined 🌟

그래서 ❗️ body안에 있는거를 보려면 라이브러리를 설치해야한다.
👉bodyParser
옛날에는 설치를 해줬어야하는데, 이제는 사람들이 많이 사용해서 express 에서 처음 깔때 바로 설치가 된다. 그래서 다른 설치는없이, 그냥 사용만 하면됨❗️

📌 옛날에는,

app.js

const bodyParser = require('body-parser'); //bodyParser 설치후 불러와서

app.use(bodyParser.json()); //사용

📌 현재는,

app.js

app.use(express.json()); //express에 내장되있으니 바로 사용가능

👉 추가를 해줘야 사용가능


app.js

//회원 한명 추가
app.post('/api/users', (req, res) => {
    console.log('req.body', req.body);
  //req에 body 안에 다 넣어놨다
    res.json('포스트요청에 대한 응답완료!');
});

그런데 여기서, 또 ❗️ req.body출력하니 이제 undefined는 아닌데, 아무것도 없는,{ }가 나왔다.
그러면 req.body는 ❓
객체이다.

📝 근데, 왜 빈 객체가 나온거지 🤨❓❓

🌟 input안에 속성 name 을 줘야한다❗️

name속성이 없었을때는 body안에서 이름이 없기때문에, 값도 🚫

name="qqq" input 에는 안녕입력
name="bbb" input 에는 123입력

👇

body{
	qqq: '안녕',
    bbb: '123'
    }

이렇게 👉 input tagname에 설정된 이름입력된값을 담아서 전달해준다!

<Input name="email" />
<Input name="pw" />
...

🔎 이렇게, body에 값을 넣어서 전달해준다. (데이터는body에 들어간다)

body{
	email: 'suji@test.com '
    pw: '1234'
   	}

👇
signup.js

<AuthForm onSubmit={submitHandler} method="GET" action="/api/users">
      <InputBoxWrap>
        <div className="input-box">
          <Input name="email" onChange={emailInputHandler}
            type="text" placeholder="아이디" />
          <ErrMsg>{
            emailErrMsg
          }</ErrMsg>
        </div>
        <div className="input-box">
          <Input name="pw" onChange={passwordInputHandler}
            type="password" placeholder="비밀번호" />
          <ErrMsg>
            {
              passwordErrMsg
            }
          </ErrMsg>
        </div>
        <div className="input-box">
          <Input onChange={passwordCheckInputHandler}
            type="password" placeholder="비밀번호 확인" />
          <ErrMsg>{
            passwordCheckErrMsg
          }</ErrMsg>
        </div>
        <div className="input-box">
          <Select name="question" onChange={onSelectHandler}>
            <Option value={1}>내가 태어난 곳은?</Option>
            <Option value={2}>어린시절 나의 별명은?</Option>
            <Option value={3}>나의 강아지 이름은?</Option>
          </Select>
          <Input name="answer" onChange={onAnswerInputHandler}
            type="text" placeholder="이메일을 찾을 때의 질문에 답하세요" />
          <ErrMsg>{answerErrMsg}</ErrMsg>
        </div>
      </InputBoxWrap>
      <Button>회원가입하기</Button>
    </AuthForm>

get요청url주소 로 받고

🔎 ?앞은 👉 경로를 보여주고 ,
검정색안은 전달하는 데이터를 보여주는데, &는 👉 데이터 하나씩 보여주면서 email & pw & question & answer데이터들을 받은것을 알수있다.
📝 input tag속성name 쓴대로 이름이 출력되는것을 확인할수있다.


post요청body객체로 넣어서 받는다.

👉 data를 가져오려면..
app.js

app.use(express.urlencoded({ extended: true }));//어떻게 가져올건지 설정하는것

어떤형식으로 가져올것인가 ❓

{ extended: true }

ture로 쓰면 중첩된 형태로 바꿔서 쓰겠다

{ extended: false }

false로 쓰면 그대로 쓰겠다

console.log(req.body) 출력값은: 내가 입력한 👇

그런데 ❗️ 아무것도 입력하지 않았는데도 ''빈 데이터가 그냥 전송이된다.
그러면 안되잖어 ❗️ 🤨 그래서 체크를 해줘야겠지 ❓

form tag 안에서, onSubmit 속성을 만들고
submitHandler 함수를 만든다

const submitHandler = (e)=>{
    // submit Event가 발생하면 실행되는함수,
    // e에는 발생한 이벤트 객체가 대입이 된다.
    // e.preventDefault() 함수는 이벤트의 기본 동작을 막는 함수이고,
    // submit 이벤트의 기본 동작은 데이터를 전송하는 것이므로, 전송을 막는 것
    e.preventDefault();

    let check = true; //정상적으로 입력하면 값이 true 

    // 이메일 input 태그 확인
    // state변수 email 확인
    if(email === ''){
      setEmailErrMsg('이메일은 필수 입력 값입니다.');
      check = false; //정상적으로 입력안되고 값이 없으면 false로 바꿔줘
    }else if(!email.includes('@')){ 
      setEmailErrMsg('이메일 형식을 지켜주세요');
      check = false;
    }else{
      setEmailErrMsg('');
    }

    // 비밀번호 입력 확인
    // state변수 password 확인
    if(password === ''){
      setPasswordErrMsg('비밀번호는 필수 입력 값입니다.');
      check = false;
    }else if(password.length < 6){
      setPasswordErrMsg('최소 6글자 이상으로 작성해주세요');
      check = false;
    }else{
      setPasswordErrMsg('');
    }

    // 비밀번호 확인 입력 확인
    // state변수 passwordCheck
    if(passwordCheck ===''){
      setPasswordCheckErrMsg('비밀번호 확인은 필수 입력 값입니다.');
      check = false;
    }else if(passwordCheck !== password){
      setPasswordCheckErrMsg('비밀번호가 일치하지 않습니다.');
      check = false;
    }else{
      setPasswordCheckErrMsg('');
    }

    // 대답 입력 확인
    // state변수 answer 확인
    if(answer === ''){
      setAnswerErrMsg('이메일 찾기 응답은 필수 입력 값입니다.');
      check = false;
    }else{
      setAnswerErrMsg('');
    }

    // 모든 입력 값들이 정상적으로 입력 되었다면 
    // submit
    if(check){
      // alert('정상입력됨!');
      // 서버로 전송!
      console.log(e.target);
      // e.target.submit(); //전통적인방식임 하지만 axios를 써보자!

      axios.post('/api/users', {
        email , 
        password,
        question,
        answer
      }).then((res)=>{
        console.log(res)
      }).catch((err)=>{
        console.log(err);
      });
      //결과값으로는 app.js 에서 쓴 req.body에
      //{
      	//email:'test@test.com'
      	//password:'1234'
      	//question: 1
      	//answer:'경기도'
      //}
      //사용자가 입력한 값이 들어간다. 
      console.log('☺️');
    }
  }

📝 axios는 ❓비동기함수이다.-2:40

res.json 의 응답은 어디서 볼수있다❓

 .then(()=>{})
//응답이 성공했을떄, 응답한 정보를 받아온다
 console.log('☺️'); //먼저 출력되고 
 //그다음 데이터가 온다. // res.json

자 이제 query를 만들어줘야지 ❗️

app.js

//회원 한명 추가
app.post('/api/users', (req, res) => {
   console.log('req.body', req.body);

   pool.query(`INSERT INTO tbl_users
   (email, pw, question, answer)
   VALUES (?, ?, ?, ?)
   `, [req.body.email, req.body.password, req.body.question, req.body.answer],
       (err, result, fields) => {
           console.log('err', err);
           if (err !== null) {
               res.status(400).json('실패야...');
           } else {
               console.log('result:', result);
               console.log('fields:', fields);
               res.json('성공이야~!!');
           }
       }
   );
});

🤨🔎 여기서 자세히 문법을 설명을 해보자 ❗️

pool.query(sql명령어, [옵션가능배열=배열값에 무었이 들어가는지 써줌], (함수)=>{}) 
//3가지 덩어리로 되어있는것이다.
 pool.query(`INSERT INTO tbl_users
    (email, pw, question, answer)
    VALUES (?, ?, ?, ?)`,  //🌟 바뀌어야하는부분은 물음표로 써준다 🌟 //이게 첫번째자리 sql 명령어. 
     [req.body.email, req.body.password, req.body.question, req.body.answer], //🌟이건 두번쨰자리 옵션가능 배열 =배열값에 무었이 들어가는지.🌟
     (err, result, fields) => {   // 이 함수의 매개변수로 3개 들어온다.
            console.log('err', err);
            if (err !== null) { //실패했다면,
                res.status(400).json('실패야...'); //그냥 res.json('실패야')라고 하면 모른다 실패인지 성공인지 그래서 이러게 status(400)를 써줘야함!
            } else { //성공했다면,
                console.log('result:', result); //객체로 결과나옴
                console.log('fields:', fields);
                res.json('성공이야~!!'); //mysql가서 확인하고 알려준다.
            }
        } //함수
     );
});
.then 👉 성공했을때
.catch 👉 실패 했을떄

pool.query는 비동기 함수이다 ❗️ 2:53-9/25

mysql 에서 명령어 실행되는동안, 함수가 실행이된다. 즉 mysql 명령어 실행후 함수가 실행됨.
그래서 res.json('성공이야~!!');함수안에 넣어줘서 mysql가서확인한다음, 성공인지 아닌지 알려줄수있다.

🌟🌟 status(400) 오류 상태코드 사용❗️

res.json('실패야...'); //출력은 실패야 라고 써있지만 진짜 실패인지 아닌지 알수없음  ❗️ 생략되서 status 200으로됨 
res.status(400).json('실패야...'); //오류가 나면 

🔎 📝 코드설명:

📌 submitHandler(함수) 버튼을 클릭하면(post하면), /api/users 경로로,
데이터 4개(email,password,question,answer) body에 넣어서 요청함.
.then은 3분이 지나고 res.joson에서 응답을 받아와야 실행할수있다.

.then((res)=>{
        console.log(res)
   // express서버에서 받아온 정보가 들어감

app.js
📌 /api/users 에서 요청이 왔으니까, 함수가 실행이 될것이다. req는 body안에 들어있다.
실행되는데 한 3분정도 걸리니깐,
아직 실행이 끝나지 않았지만, console.log('dddd'); 먼저 실행이된다.
실행 다 됬고 3분이 지나서 응답res.joson으로 받을수있다.

profile
나를위한 노트필기 📒🔎📝

0개의 댓글