[React] 흔하디 흔한 투두리스트 아니고 로그인 - 2

loginContainer 컴포넌트 만들기

import React from 'react';
import { useDispatch } from 'react-redux'; // ( 1 )
import SignInForm from '../components/Auth/SignInForm';
import { signInRequestAction } from '../redux/action/auth'; // ( 2 )
import { Router } from "react-router-dom";

function AccountContainer () {

    const dispatch = useDispatch();

    const onSignIn = (user) => dispatch(signInRequestAction(user)); // ( 3 )

    const signInForm = () => (<SignInForm onSignIn={onSignIn}/>); // ( 4 )

    return(
        <div className="body_wrapper">
            <Switch>
            <Router exact path="/accounts/signin" component={signInForm} /> // ( 4 )
            </Switch>
        </div>
    )
}

export default AccountContainer;

src/containers/AccountContainer.js 파일을 만들었다.
해당 컨테이너 컴포넌트에서 계정 관련한 라우팅을 잡는다.
( 1 ) -> react-redux모듈이 제공하는 useDispatch 함수를 통해 action을 디스패치 (실행, 발생) 시킬 수 있다.
( 2 ) -> createAction함수를 통해 만든 action 생성 함수를 import해서 사용한다.
( 3 ) -> 어떠한 action을 dispatch할 때는 dispatch 함수의 인자로 action을 넣어준다.
( 4 ) -> 필자는 SignInForm 컴포넌트에 onSignIn dispatch 함수를 넣어 리턴하는 함수를 생성해 라우트 컴포넌트로 넣어줬다.

SignInForm 컴포넌트 만들기

import React, { useState } from 'react'; // ( 1 )

const SignInForm = ({ onSignIn }) => {

    const [email, setEmail] = useState(''); // ( 2 )
    const [password, setPassword] = useState(''); // ( 3 )

    const _handleChange = (event) => {
        const { target: { name, value } } = event // 비구조화 할당
        if(name === 'email') {
            setEmail(value); // ( 4 )
        } else if(name === 'password'){
            setPassword(value); // ( 5 )
        }
    }

    const onSubmit = () => {
        const user = {
            email,
            password
        }
        onSignIn(user); // ( 6 )
        setEmail(''); // 인풋 초기화
        setPassword('');
    };

    return(
        <div>
            <div>
              <label>이메일</label>
              <input name = "email" type="text" placeholder="saasland@gmail.com" value={email} onChange={_handleChange}/>
            </div>
            <div>
              <label>비밀번호</label>
              <input name= "password" type="password" placeholder="******" value={password} onChange={_handleChange}/>
            </div>
            <button className="login-button" onClick={onSubmit}>로그인</button>
        </div>
    )
}
export default SignInForm;

src/components/SignInForm.js 간단한 형태의 로그인 컴포넌트를 만들었다.
( 1 ) -> 상태 관리를 위하여 useState hook을 사용한다.
( 2 ) -> email state를 초기화한다.
( 3 ) -> password state를 초기화한다.
( 4 ) -> email input태그에 입력된 값을 email state에 변경한다.
( 5 ) -> password input태그에 입력된 값을 password state에 변경한다.
( 6 ) -> 로그인 버튼이 눌렸을 때 props로 받은 onSignIn 액션 디스패치 함수에 email과 password를 담은 객체를 인자로 넣어 실행한다.

onSignIn 함수가 실행되면 signInRequestAction 액션이 디스패치되어 reducer에서 state값을 변동할 수 있다.

요약

  • 이전 포스팅에서 생성한 redux action과 reducer, dispatch를 이어주었다.
  • 실행 흐름
  • email과 password를 입력한 후 로그인 버튼을 누른다.
  • SignInForm 컴포넌트에서 props로 받은 onSignIn 액션 dispatch 함수에 객체를 넣어주며 호출한다.
  • 로그인 액션이 생성되며 dispatch된다.
  • redux-saga 미들웨어의 제너레이터 함수가 실행된다. -> 비동기 통신, 또 다른 액션 dispatch를 여기서 처리한다.
  • saga 제너레이터 함수에서 비동기 통신을 한 후 해당 결과값으 성공 액션 or 실패 액션에 서버 응답값을 넣어 dispatch 한다.
  • 성공 액션 or 실패 액션의 reducer에서 redux store의 state값을 변경시켜준다.(불변성을 지켜줘야함)
© 2020 JunhoBaik, Built with Gatsby