(수근수근)
[react] socket.io 로 채팅 만들기 본문
다음 글은 아래의 유튜브 영상을 보고 정리한 내용입니다.
code : https://github.com/NikValdez/ChatAppTut
출처: www.youtube.com/watch?v=CgV8omlWq2o
react - chatting -app
목차
- 전체 프로젝트 구조
- socket.io 모듈 및 function
- server 소스
- Client 소스
- REACT STUDY
- function vs class
- useEffect & useState
- cors Error 해결
- 추가) room 나누기
전체 프로젝트 구조
다음은 전체 프로젝트 구조입니다.
Client와 Server가 소켓통신을 통해서 서로 통신을 주고 받습니다.
- chat 폴더 : Client 역할
- Server 폴더 : server역할
Socket.io 모듈 및 function
- socket.io란
socket.io란 websocket기반으로 클라이언트와 서버간의 양방향 통신을 가능하게 해주는 모듈입니다.
기본적인 socket의 연결, 해제기능들을 자바스크립트로 가능하게 만든 모듈이라 생각하시면 편할 것 같습니다.
기본적인 socket의 실행흐름에 대해 알고 사용하는 것이 더 의미가 있을 것 같습니다.
- socket 핵심 function
emit : 데이터 전송 (서버-> 클라이언트 / 클라이언트 -> 서버)
on :데이터를 받는다 (서버-> 클라이언트 / 클라이언트 -> 서버)
Server 설정 및 소스
- 환경 설정(server폴더에서 아래의 명령어 실행 )
- npm install express
- npm install cors
- npm install nodemon
- npm install socket.io
// path : chat/server/index.js
const app = require('express')()
const server = require('http').createServer(app)
const cors = require('cors')
const io = require('socket.io')(server,{
cors : {
origin :"*",
credentials :true
}
});
io.on('connection', socket=>{
socket.on('message',({name,message}) => {
io.emit('message',({name, message}))
})
})
server.listen(4000, function(){
console.log('listening on port 4000');
})
- 제공되는 코드에서는 cors 부분이 빠져있는데 그대로 코드를 실행한 경우 다음과 에러가 났다.
cors : { origin : "*", credentials : true} 를 코드에 추가 시켜서 문제해결
Client 설정 및 소스
- 환경설정 (CHATTING폴더에서 아래의 명령어 실행)
- npx create-react-app chat
- cd chat
- npm install socket.io-client //socket client모듈
- npm install @material-ui/core //react UI입니다
- App.css 내용은 위에 깃허브에 있습니다.
// paht : CHATTING/chat/App.js
import React, {useState, useEffect} from 'react';
import io from 'socket.io-client';
import TextField from '@material-ui/core/TextField';
import './App.css';
const socket = io.connect('http://localhost:4000')
function App() {
const [state, setState] = useState({message:'', name:''})
const [chat,setChat] =useState([])
useEffect(()=>{
socket.on('message',({name,message})=>{
setChat([...chat,{name,message}])
})
},[])
const onTextChange = e =>{
setState({...state,[e.target.name]: e.target.value})
}
const onMessageSubmit =(e)=>{
e.preventDefault()
const {name, message} =state
socket.emit('message',{name, message})
setState({message : '',name})
}
const renderChat =()=>{
return chat.map(({name, message},index)=>(
<div key={index}>
<h3>{name}:<span>{message}</span></h3>
</div>
))
}
return (
<div className='card'>
<form onSubmit={onMessageSubmit}>
<h1>Message</h1>
<div className="name-field">
<TextField
name ="name"
onChange={e=> onTextChange(e)}
value={state.name}
label="Name"/>
</div>
<div >
<TextField
name ="message"
onChange={e=> onTextChange(e)}
value={state.message}
id="outlined-multiline-static"
variant="outlined"
label="Message"/>
</div>
<button>Send Message</button>
</form>
<div className="render-chat">
<h1>Chat log</h1>
{renderChat()}
</div>
</div>
);
}
export default App;
REACT STUDY
[ class vs function ]
Hooks이 나오기 전에 class component는 react component의 모든기능이 가능했지만
function에서는 제약사항이 많았다.
최신 리액트에서는 hooks이 등장하면서 funcion component 기존 class의 작업이 가능해졌다
hook이란?
class 없이 state를 사용할 수 있는 새로운 기능
[ useState ]
- 동적인 상태인 state를 관리하기 위해 나온 HOOK
- 함수형 컴포넌트에서도 state관리가 가능해짐
기존 클래스 컴포넌트에서 state관리
초기값 설정의 constructor에서 진행해주었고, 상태값을 this를 통해서 불러올 수 있었다.
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
반면에 함수 컴포넌트에서는 상태값을 가지고 오기 위해서는 props로 데이터를 전달해주어야했다.
이를 해결하기 위해 Hook이라는 것을 소개 했고 useState를 활용하여 function component에서도
이제 state의 특징을 사용할 수 있다.
import React, { useState } from 'react';
function Example() {
// 새로운 state 변수를 선언하고, count라 부르겠습니다.
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
[ useEffect ]
- useEffect render() 가 끝났을 때 ,렌더가 실행될때마다 실행된다
- 클래스의 life cycle 에서 componentDidMount/ componentDidUpdate 를 대신하는 것이다.
- 렌더링 이후에 작업되는 것으로써 네트워크통신이나, 컴포넌트와 상관없는 것들을 변경될 때 사용된다
- useEffect는 여러개 설치할 수 있다.
- useEffect의 리턴값에 함수를 제공하면 마무리하는 작업을 진행할 수 있다.(clean up)
- 두번째 원소값을 배열에 넣으면, 그 값이 바뀌지 않으면 useEffect작업을 진행하지 않는다.
'web > React' 카테고리의 다른 글
react memoization 2 ) React.memo (1) | 2023.10.09 |
---|---|
react memoization 1 ) 왜 최적화 툴이 필요한가? (0) | 2023.10.09 |
useEffect callback함수 async키워드를 쓰면 안되는 이유 (0) | 2023.10.08 |
datepicker 자동 masking하기 (0) | 2023.01.05 |
리액트 내장 Hooks (0) | 2021.08.03 |
Comments