본문 바로가기

영어쌤의 놀이방_ 수퍼.코드.파티/리액트와 장고로 회원가입 관리 만들어욤

(3.4) Implementing React_ Redux & HTTP. 영어쌤이 만드는 회원가입, 인증[CRUD] 만들어욤! 리액트와 파이썬 장고

반응형

(3.4) Implementing React_ Redux & HTTP.
영어쌤이 만드는 회원가입, 인증[CRUD] 만들어욤! 리액트와 파이썬 장고

안녕하세요? 웹개발 하는 영어쌤 좌니 입니당~.

- 이번 포스팅은 3.3 에서 언급했듯이 계정 정보 입력 및 Submit 기능을 만들어 볼 차례입니다.

(23) add lead form(계정 정보 입력) User Interface 만들기 || /src/components/leads/Form.js

- 사용자의 입장에서 정보를 입력하기 위해서 당연히 입력 창이 필요합니다.
- 그러니 state들을 추가 작성해 보도록 합니다.
(2.4) Implementing React_ 서버 최신화 자동화에서 작성했던 From.js 에 정보 입력 폼을 위한 코드를 추가로 작성해 줍니다.

// Form.js
import React, { Component } from 'react'

export class From extends Component {
	state = {
    	name: '',
        email: '',
        message: ''
    }
	
    render() {
    	return (
        	<div>
            	<h1>Add Lead Form</h1>
            </div>
        )
    }
}

export default Form

- 위의 Form.js에 state를 추가해 주었습니다.
- 그리고 다음 작업은 render 부분입니다. 여기선 직접적으로 UI에 표출되는 부분입니다. Add Lead Form 이라 되어 있는 부분을 이제는 실제 입력창이 있는 form으로 바꿔줄 것 입니다.

// Form.js
import React, { Component } from 'react';

export class From extends Component {
	state = {
    	name: '',
        email: '',
        message: ''
    }
	
    onChange = e => this.setState({ [e.target.name]: e.target.value });
    
    onSubmit = e => {
    	e.preventDefault();
        console.log("submit");
    }
    
    render() {
    	const { name, email, message } = this.state;
    	return (
        	<div className="card card-body mt-4 mb-4">
            	<h2>Add Lead</h2>
                <form onSubmit={this.onSubmit}>
                	<div className="form-group">
                    	<label>Name</label>
                        <input
                        	className="form-control"
                            type="text"
                            name="name"
                            onChange={this.onChange}
                            value={name}
                        />
                    </div>
                   	<div className="form-group">
                    	<label>Email</label>
                        <input
                        	className="form-control"
                            type="email"
                            name="email"
                            onChange={this.onChange}
                            value={email}
                        />
                    </div>
                    <div className="form-group">
                    	<label>Message</label>
                        <input
                        	className="form-control"
                            type="text"
                            name="message"
                            onChange={this.onChange}
                            value={message}
                        />
                    </div>
                    <div className="form-group">
                    	<button type="submit" className="btn btn-primary">
                        	Submit
                        </button>
                    </div>
              </form>
         </div>
        )
    }
}

export default Form

이미지 자료

onChange(10번째 줄)를 추가함
onChange 추가 전이라서 줄수에 차이가 있습니다. // name
email
message
Submit 버튼


- 코드 초반부의 state 내의 name, email, message와 html 태그 내의 this.onChange, value 와 같은 것들은 거로 연결되어 있어서 변화를 주거나 하면 반영이 되도록 하는 역할이 합니다. 

결과화면

정보 입력 form 

- email부분은 type도 email로 지정해 줬기 때문에 형식을 따라야 합니다. 그렇지 않으면 자동으로 위와 같은 오류 메세지를 발생시킵니다.
- 그러면 형식에 맞춰 입력 후 Submit 버튼을 클릭하여 동작 테스트를 합니다.

입력 및 제출 폼 동작 테스트 진행

- 위와 같이 콘솔창에서 Submit 메세지가 발생되면 1차 테스트는 통과입니다.

(24) 동작(action) 코드 작성 || /src/actions/leads.js
에 동작코드(Submit, 신규 생성 데이터 제출) 추가 작성하기

- Submit 버튼의 작동 유무는 확인했고 이상 없습니다.
- 그러면 실질적으로 'Submit' 버튼을 클릭했을때, 그에 반응하는 action(동작)을 구현해 줘야 합니다.
- 여기서 구현할 동작이란, 'Add lead' 즉, 신규 data 저장(등록)을 의미합니다.

구현 목표

- 이번 시간의 우리의 목표는 1번의 양식을 채워 Submit 버튼을 클릭하면,
- 그대로 서버에 해당 Data를 추가합니다.
- 그러면 Lead의 List를 보여주는 2번 UI에 반영이 되도록 합니다.

- /src/actions/leads.js || ADD_LEAD 추가 01

import axios from 'axios';

/*import 에서 DELETE_LEAD 뒤에 ADD_LEAD 를 하나 더 추가해 줍니다.*/
import { GET_LEADS, DELETE_LEAD, ADD_LEAD } from './types';

// GET LEADS
export const getLeads = () => dispatch => {
	... ...
};

- /src/actions/types.js || ADD_LEAD 추가

// /src/actions/types.js
export const GET_LEADS = "GET_LEADS";
export const DELETE_LEAD = "DELETE_LEAD";
export const ADD_LEAD = "ADD_LEAD";

- /src/actions/leads.js || ADD_LEAD 추가 02

// lead.js axios 활용예정
import axios from 'axios';

import { GET_LEADS, DELETE_LEAD } from './types';

// GET LEADS
export const getLeads = () => dispatch => {
	axios.get("/api/leads/")
    	.then(res => {
        	dispatch({
            	type: GET_LEADS,
                payload: res.data
            });           
        })
        .catch(err => console.log(err));
};

// DELETE LEAD
export const deleteLeads = (id) => dispatch => {
	axios.delete(`/api/leads/${id}/`)
    	.then(res => {
        	dispatch({
            	type: DELETE_LEADS,
                payload: id
            });           
        })
        .catch(err => console.log(err));
};

// ADD LEADS
export const addLeads = () => dispatch => {
	axios.post("/api/leads/") // 실제 데이터를 보내기 위한 명령어도 POST입니다. 그러니 post로!
    	.then(res => {
        	dispatch({
            	type: ADD_LEADS,
                payload: res.data
            });           
        })
        .catch(err => console.log(err));
};

leads.js에 추가한 코드

(25) /src/reducers/leads.js 수정

- leads.js에 새로운 기능인 add를 추가해 줍니다.

// leads.js
import { GET_LEADS, DELETE_LEAD, ADD_LEAD } from '../actions/types.js';

const initialState = {
    leads: []
};

export default function(state = initialState, action) {
	switch(action.type) {
    	case GET_LEADS:
        	return {
            	...state,
                leads: action.payload
            };
            case DELETE_LEAD:
            return{
            	...state,
                leads: state.leads.filter(lead => lead.id !==
                action.payload)
            };
            case ADD_LEAD:
            	return{
                	...state,
                    leads: [...state.leads, action.payload]
                }
          default:
          	return state;
    }
}

(26) /src/components/leads/Form.js 수정

- Form.js에 새로운 기능인 add를 추가해 줍니다.

// Form.js
import React, { Component } from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import { addLead } from '../../actions/leads';

export class From extends Component {
	state = {
    	name: '',
        email: '',
        message: ''
    }
	
    static propTypes = {
    	addLead: PropTypes.func.isRequired
    };
    
    onChange = e => this.setState({ [e.target.name]: e.target.value });
    
    onSubmit = e => {
    	e.preventDefault();
        // console.log("submit");
        const { name, email, message } = this.state;
        const lead = { name, email, message };
        this.props.addLead(lead);
    }
    
    render() {
    	const { name, email, message } = this.state;
    	return (
        	<div className="card card-body mt-4 mb-4">
            	<h2>Add Lead</h2>
                <form onSubmit={this.onSubmit}>
                	<div className="form-group">
                    	<label>Name</label>
                        <input
                        	className="form-control"
                            type="text"
                            name="name"
                            onChange={this.onChange}
                            value={name}
                        />
                    </div>
                   	<div className="form-group">
                    	<label>Email</label>
                        <input
                        	className="form-control"
                            type="email"
                            name="email"
                            onChange={this.onChange}
                            value={email}
                        />
                    </div>
                    <div className="form-group">
                    	<label>Message</label>
                        <input
                        	className="form-control"
                            type="text"
                            name="message"
                            onChange={this.onChange}
                            value={message}
                        />
                    </div>
                    <div className="form-group">
                    	<button type="submit" className="btn btn-primary">
                        	Submit
                        </button>
                    </div>
              </form>
         </div>
        )
    }
}

export default connect(null, { addLead })(Form);

추가한 코드들...

- console.log("Submit"); 은 그냥 콘솔창에 메세지를 띄워주는 용도였기에 이제는 지워주고 실제 동작하는 코드를 넣어줍니다.

- addLead proptype 추가해 주기

(27) 동작 확인 테스트

브라우저 UI상에서 신규 data 입력 및 제출(추가) 동작에 이상이 없는지 확인합니다.
- 보통 동작이 안되면 코드에 작은 오타들이 있더라구요... 그럴땐 참.. T^T
- 어쨌든 테스트를 진행해 봅니다.

추가할 data 내용 입력

- 위와 같이 입력을 완료하고 Submit 버튼을 클릭합니다.

데이터 추가됨

- reload(새로고침) 을 해도 등록된데이터가 사라지거나 하는 오류는 발생하지 않으니 정상적으로 작동함을 확인했습니다.

reload(새로고침) 이후

 

- 이렇게 해서 지금까지 기존의(또는 새로 생성한) 계정 Data List를 호출해 읽고(Read), 신규 생성하며(Create) 삭제하는(Delete)까지 완료하였습니다.

- 다음 순서인
[4] - Error Handling & Alerts 에선 문자 그대로 에러 관리(예외처리 라고도 함)를 해주고 warning message를 발생시켜(Alerts)주는 기능을 만들어 보는 시간이 되겠습니다.
- 직접 모두 만들기에는 퀄리티와 기술력 부족이 따를 것 입니다. 특히 단일개발자일 경우엔 더 그렇죠.
- 그래서 다음의 컴포넌트들을 사용할 예정입니다.
- React alert(Pop-up message 발생을 위한 것)

- 예를 들면 다음의 Error Case가 있습니다.

- 위와 같이 정보 입력 이후 등록을 하려 해도 이미 동일 정보인 email이 list에 있으므로 등록이 안됩니다.
- 사용자 입장에선 안되는 이유를 알 수 없기에 그 다음 단계의 행동을 취하기 난해해집니다.
- 그렇기에 이미 다른사용자가 해당 email 계정을 가지고 있어 다른 이름의 계정을 생성하라는 메세지를 띄워 줘야 할 것 입니다.

- 콘솔창을 한번 볼까요?

- 장고 서버 포트(:8000)에서 보내준 메세지에서 볼 수 있듯이 Bad Request 라는 메세지가 발생되었습니다.
- 물론 개발자는 이것을 알 것 이지만, 이미 언급했듯이 사용자라면 '아! 내가 다른 이름의 계정을 만들어야 겠군!' 보다는 '어! 얘네 왜이래? 서버 다운된건가?' 라는 생각 부터 할 것 이고 그게 당연한 것 입니다.
- 결국 오류나 불만사항은 개발자가 떠안고가고 그걸 얼마나 빠른 시일 내에 해결하느냐가 관건이기 때문입니다. 

-그래서 우리가 만들 것은!
1. erros reducers
2. alerts component
입니다.

그러면!!! 여기서 마치고 다음 포시팅인 에서 [4] - Error Handling & Alerts뵙겠습니다!!!

 

Stay tuned for the next episode of Web development by the English teacher JOHNNYCLUB!!!

반응형