ON/React

[ React ] 회원가입 ( 로그인 / 로그아웃 ) ②

박도비 2023. 9. 12. 22:07
728x90

오늘은 이어서, 회원가입 시 로그인 / 로그아웃 및 아이디 중복 검사를 구현해보자

먼저 로그인/ 로그아웃 먼저 구현하기로 하자

 

 

[ React ] 회원가입 구현 ①

이번 시간은 이전시간에 했던 TodoList를 좀 더 업그레이드 시켜보자! Spring을 이용해서 BACK단을 구성해볼거고, React를 이용해서 Front 화면을 구현해보자. 이전에 했던 내용이 기억이 안나거나 실습

jnaa.tistory.com

📚 React

📘 App.js

import React, { useState, createContext } from 'react';
import './App.css';

import SignupContainer from './Signup';
import Login from './Login';

export const TodoListContext = createContext(); // 전역변수생성 (내보낼 수 있는)


function App() {
  // 회원가입, 로그인, 회원의 Todo List 출력/추가/제거
  const [signupView, setSignupView] = useState(false);

  // 로그인한 회원정보 저장
  const [loginMember, setLoginMember] = useState(null);

  // 로그인한 회원의 todo-list를 저장 
  const [todoList, setTodoList] = useState([]);




  return (
    <TodoListContext.Provider value={{setTodoList,setLoginMember,loginMember}}>
                      {/* 버튼을 클릭할때마다 signupView가 true변했다가 */}
      <button onClick={ () => {setSignupView(!signupView)} }>
        { signupView ? ('회원 가입 닫기') : ('회원 가입 열기')}
      </button>

      <div className='signup-wrapper'>
        {/* signupView가 true인 경우에만 회원 가입 컴포넌트 렌더링 */}
        {/* 조건식 && (true인 경우) */}
        {signupView === true && (<SignupContainer/>)}
      </div>
      
      <h1>Todo List</h1>
      <Login/>

      <br/>
      
     

    </TodoListContext.Provider>
    
  );
}

export default App;

① import Login from './Login';

: 로그인 처리를 위한  컴포넌트를 생성해주고 import 를 진행


export const TodoListContext = createContext();

: TodoListContext 를 전역 변수를 사용하는 export를 이용해서 내보냄

 

TodoListContext.Provider value={{setTodoList,setLoginMember,loginMember}}

: import 한 TodoListContext.Provider value를 이용해서  TodoListContext감싸고 있는 자식 컴포넌트에게 Context API를 이용해서   'setTodoList,setLoginMember,loginMember' 3개의 데이터를 넘겨줄 것이다. 

 

📘 Login.js

import React, { useState , useContext } from 'react'; //imrs
import { TodoListContext } from './App';



const LoginComponent = () => {

    // 전역변수 Context를 사용
    const {setTodoList,setLoginMember,loginMember} = useContext(TodoListContext);

    const [id,setId] = useState('');
    const [pw,setPw] = useState('');
    
    const login = () => {
        fetch('/login',{
            method:'POST',
            headers:{
                // 전달되는 데이터 타입 
                'Content-Type' : 'application/json',

                // 응답 데이터 타입
                'Accept':'application/json'
            },
            body:JSON.stringify({
                id : id,
                pw : pw
            })
        })
        .then(resp => resp.json())
        .then(map => {
            console.log(map)

            // 로그인 실패 시 
            if(map.loginMember === null){
                alert("아이디 또는 비밀번호가 일치하지 않습니다.")
                return;
            }

            // 로그인 성공 시 
            setLoginMember(map.loginMember)
            setTodoList(map.todoList);
            setId('')
            setPw('')
        })

    }


    const logout = () => {
        
        setLoginMember(null)
            
    }

    return (
        <div className="login-container">
            <table>
                <tbody>
                    <tr>
                        <th>ID</th>
                        <td>
                            <input type="text" onChange={e => setId(e.target.value)} value={id} />
                        </td>
                    </tr>

                    <tr>
                        <th>PW</th>
                        <td>
                            <input type="password" onChange={e => setPw(e.target.value)} value={pw} />
                        </td>
                        <td>
                            <button onClick={login} >Login</button>
                        </td>
                    </tr>
                </tbody>
            </table>

            {/* loginMember가 있다면(null값이라면) 로그아웃버튼 실행  */}
            {loginMember && (
                <button onClick={logout}>로그아웃</button>
            )}
        </div>        
    );


}

export default LoginComponent

 import { TodoListContext } from './App';

: App.js에 전역변수롤 선언해둔 TodoListContext를 사용하기 위해서 import 하기 

 

②  const {setTodoList,setLoginMember,loginMember} = useContext(TodoListContext);

TodoListContext에 있는 전역변수 사용을 위해 배열형태로 받기 

 

③ 'Accept' : 'application/json' 

: 기존에는  Spring에서 작성해서 json형태로 받아줬다면 React에서도 json형태로 받겠다는 구문 

 

④ 로그아웃 loginMember && (<button onClick ={logout}>로그아웃</button>)

: && 기준으로 왼쪽에 loginMember가 true라면 logout 실행 (false라면 실행 x)

  

 

📚 Spring

📗 TodoController.java (필요한 부분만 발췌)

   @PostMapping("/login")
   public Map<String, Object> login(@RequestBody TodoMember member){ 
      return service.login(member);
   }

 

📗 TodoService.java (필요한 부분만 발췌)

 Map<String, Object> login(TodoMember member);

📗 TodoServiceImpl.java (필요한 부분만 발췌)

 @Override
   public Map<String, Object> login(TodoMember member) {
      
      TodoMember loginMember = dao.login(member);
      
      Map<String, Object> map = new HashMap<>();
      map.put("loginMember", loginMember);

      if(loginMember != null) {
         List<Todo> todoList = dao.selectTodoLst(loginMember.getTodoMemberNo());
         map.put("todoList", todoList);
      }
      
      return map;
   }

📗 TodoDao.java (필요한 부분만 발췌)

  public TodoMember login(TodoMember member) {
      return sqlSession.selectOne("todoMapper.login", member);
   }

   public List<Todo> selectTodoLst(int todoMemberNo){
      return sqlSession.selectList("todoMapper.selectTodoLst", todoMemberNo);
   }

📗 todo-mapper.xml (필요한 부분만 발췌)

   <select id="login" resultMap="todoMember_rm">
      SELECT * FROM TODO_MEMBER
      WHERE ID = #{id}
      AND PW = #{pw}
   </select>
   
    <select id="selectTodoLst" resultMap="todo_rm">
      SELECT * FROM TODO_LIST
      WHERE TODO_MEMBER_NO = #{todoMemberNo}
      ORDER BY 1
   </select>

💻 출력 화면 

 

728x90