본문 바로가기
개발 Study/React

[React] 실시간 채팅 구현하기 - Login 페이지 생성

by jiyoon_92 2022. 7. 25.
반응형

react

그냥 js로 채팅기능 예제만 실행해 봤으나 본격적으로 react도 공부해볼겸 react로 client 구현을 제대로? 시작해보려고한다. 

우선 CRA (Create-React-App)으로 리액트 프로젝트를 생성한다. 프로젝트 생성은 이전 글을 참고한다.

2022.07.04 - [개발 Study/Node, js, react] - [React] npm으로 react 프로젝트 생성하기

 

[React] npm으로 react 프로젝트 생성하기

1. Node.js 를 설치하여 npm 라이브러리 설치하기 앞선 글에서 Node.js 를 설치하여 npm 및 관련 라이브러리들을 설치하는 방법을 작성했으므로 아래 글을 참조한다. https://chuun92.tistory.com/13 [Node.js] No..

chuun92.tistory.com

 

1. Functional component 활용하기

최신 react에서는 useState, useEffect, useRef, useNavigate 등의 Hook이라는 기능을 이용하여 functional component를 활용하도록 되어있다. 앞으로 Class component보다는 Functional Component + hook 조합으로 구현하는 것을 권장하기 때문에 모든 Component를 Functional Component로 열심히? 구현해보겠다.

우선 Class Component에 비해 적은 양의 코드로 빠르게 구현 가능하다. 다만 명확하게 개념을 이해하고 사용해야 실수를 줄일 수 있다. 함수 안에 사용할 변수나 함수를 구현하고 return() 값 안에 html 태그들을 넣은 다음 {} 로 함수 내에 선언된 state,prop,hook,변수 등을 참조하여 활용할 수 있다.

아래는 Span 태그를 반환하는 Component로 text를 props로 받아 data-placeholder에 넣어준다.

function CustomSpan({text}) {
    return <span className="focus-input-nickname" data-placeholder={text}/>
}

 

2. Hook 활용하기 - UseState, UseEffect, UseNavigate 

  • UseState : 컴포넌트 내에서 State를 저장하며 [(저장할 State 변수), (setState용 함수명)] = useState((Type)) 으로 선언하여 사용한다. 
  • UseEffect : 배열 내에 있는 변수들의 값이 변경되면 UseEffect 내에 선언된 함수가 실행된다. [] 빈 배열로 두는 경우 Component가 생성될 때 한번만 실행된다.
  • UseNavigate : Router를 이용하여 다른 페이지로 이동시킬 때 사용한다.

 

import React from 'react';
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import Button from '../components/button'
import '../css/styles.css';
import '../css/login-styles.css';

import { login } from '../client'

function CustomSpan({text}) {
    return <span className="focus-input-nickname" data-placeholder={text}/>
}

function Login(props) {
    console.log('rendered : Login')
    const [nickname, setTextValue] = useState('');
    const [focused, setFocusValue] = useState(false);
    const [placeholder, setHolderValue] = useState('Nickname');
    const navigate = useNavigate();
    useEffect(()=>{
        if (focused === true || nickname !== '') {
            if (placeholder !== '')
                setHolderValue('');
        }
        else {
            if (placeholder !== 'Nickname')
                setHolderValue('Nickname');
        }
    }, [focused, nickname, placeholder]);
    const handleSetValue = (e) => {
        if (nickname !== e.target.value)
            setTextValue(e.target.value);
    }
    const handleFocusValue = (value) => {
        if (focused !== value)
            setFocusValue(value);
    }
    
    const loginButtonClick = () => {
        let success = login(nickname);
        if (success)
        {
            console.log('login success ', nickname);
            navigate(`/main`, {replace : false, state : { user : nickname}});
            props.HandleLocation(`/main`);
        }
    }

    return(
        <div className='div-login-container'>
            <div className='div-wrap-login'>
                <div className='div-form-login'>
                    <span className="login-form-title p-b-26">Welcome</span>
                    <div className='div-wrap-login-validate-input'>
                        <input className="input-normal" type="text" name='nickname' 
                     onChange={(e)=>handleSetValue(e)} onFocus={(e)=>handleFocusValue(true)} onBlur={(e)=>handleFocusValue(false)}/>
                        <CustomSpan text={placeholder}/>
                    </div>
                    <div className='div-login-container-form-btn'>
                     <Button type="button btn-2" id="btn-login" text="Login" onClick={loginButtonClick} width={150} height={50} />
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Login;

'nickname'을 입력하여 로그인하는 페이지를 작성해보았다. 우선 input 에 placeholder로 'Nickname'을 적는 란으로 표시하고 싶어서 CustomSpan을 만들어 그 위에 올렸다. Re-rendering을 방지하고자 UseEffect 내에 조건문을 넣어 placeholder 값을 변경하였다. input에 focus가 있는 경우 placeholder가 사라지도록 구현하였으며, nickname 작성후 focus out이 일어나더라도 placeholder가 없도록 만들었다.

State로는 Input으로 작성된 nickname과 input에 적용된 focus 상태, 그리고 span에 적용되는 placeholder를 관리한다. 

Login 버튼 클릭 시 로그인 한 Nickname을 파라미터로 넘겨주며 Router를 이용하여 Main페이지로 넘어가도록 구현했다.

 

3. 완성된 로그인 컴포넌트

로그인 페이지

 

Nickname 입력

 

다음엔 대화 목록을 구현하고, Router로 페이지 이동을 해보도록 하겠다. ㅎㅎ

반응형

댓글