[React Native] ์ค์๊ฐ ์ฑํ ์ฑ ๋ง๋ค์ด๋ณด๊ธฐ 2 - Websocket ์ด์ฉํ์ฌ ํ๋ก ํธ ๊ตฌํํ๊ธฐ (Build a real-time chatapp 1 - Implement frontend with websocket)
์๋ ํ์ธ์ Foma ์ ๋๋ค.
์ง๋ ๊ธ์ Node.js๋ก ์น์์ผ ์๋ฒ๋ฅผ ๊ตฌํํ๋๋ฐ์.
์ค๋์ React Native์์ ํด๋น ์๋ฒ๋ฅผ ์ด์ฉํ์ฌ ์ค์๊ฐ์ผ๋ก ์ฑํ ์ ์ฃผ๊ณ ๋ฐ๋ ๊ธฐ๋ฅ์ ๊ตฌํํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋ฐ๋ก ์์ํ ๊ฒ์~
(ํ๊ฒฝ์ React Native CLI + Typescript ์ ๋๋ค.)
Tutorial
- ์ค์๊ฐ ์ฑํ ์ฑ ๋ง๋ค์ด๋ณด๊ธฐ 1 - Websocket ์ด์ฉํ์ฌ ๋ฐฑ์๋ ๊ตฌํํ๊ธฐ (feat. Websocket) (Build a real-time chatapp 1 - Implement backend with websocket)
- ์ค์๊ฐ ์ฑํ ์ฑ ๋ง๋ค์ด๋ณด๊ธฐ 2 - Websocket ์ด์ฉํ์ฌ ํ๋ก ํธ ๊ตฌํํ๊ธฐ (Build a real-time chatapp 1 - Implement frontend with websocket)
Install
react-native-device-info
React Native์์ ๋๋ฐ์ด์ค ์์ด๋๋ฅผ ์์๋ด๊ธฐ ์ํ ๋ชจ๋
npm install react-native-device-info@8.4.5
Preview
Model
Message.ts
interface Message {
user: string;
message: string;
}
Set state
1. serverState
์๋ฒ์ ์ํ๋ฅผ ์ ์ฅ
2. messageText
์ธํ์ฐฝ์ ์ ๋ ฅ๋๋ ๋ฉ์ธ์ง์ ์ํ๋ฅผ ์ ์ฅ
3. serverMessages
์๋ฒ์์ ๋ฐ์์จ ๋ฉ์์ง๋ค์ ์ํ๋ฅผ ์ ์ฅ
const ChatScreen = () => {
const [serverState, setServerState] = useState('Loading...');
const [messageText, setMessageText] = useState('');
const [serverMessages, setServerMessages] = useState([]);
...
Set variables
์์์ ์ค์นํ react-native-device-info์์ getUniqueId๋ฅผ import ํฉ๋๋ค.
import {getUniqueId} from 'react-native-device-info';
๋๋ฐ์ด์ค ์์ด๋๋ฅผ userId๋ก ์ ์ฅํด ์ค๋๋ค.
let userId = getUniqueId();
์๋ฒ์ ๋ฉ์ธ์ง๋ค์ ๋ฐ์์ฌ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
const serverMessagesList: Message[] = [];
Set websocket methods
webSocket์ useRef๋ก ์ ์ฅํด ์ค๋๋ค.
const webSocket = useRef(null);
useEffect๋ฅผ ์ฌ์ฉํ์ฌ ์น์์ผ ์ธ์คํด์ค๋ฅผ ๋ก์ปฌ ํธ์คํธ ์์ดํผ์ ํจ๊ป ์์ฑํด ์ค๋๋ค.
useEffect(() => {
webSocket.current = new WebSocket(`ws://๋ก์ปฌํธ์คํธ์์ดํผ`);
...
์๋ฒ๊ฐ ์ฐ๊ฒฐ๋์์ ๋ ์๋ฒ์ ์ํ๋ฅผ ๋ณ๊ฒฝํด ์ค๋๋ค.
webSocket.current.onopen = () => {
setServerState('Connected to the server');
};
์๋ฒ์์ ์ด๋ค ๋ฉ์ธ์ง๊ฐ ์์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ํ์ฑํ๊ณ severMessageList์ ๋ฃ์ ๋ค ์๋ฒ ๋ฉ์ธ์ง์ ์ํ์ ์ถ๊ฐํด ๋ณ๊ฒฝํด ์ค๋๋ค.
webSocket.current.onmessage = e => {
let parse = JSON.parse(e.data);
serverMessagesList.push(parse);
setServerMessages([...serverMessagesList]);
};
์๋ฒ์์ ์ด๋ค ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ์๋ฒ์ ์ํ๋ฅผ ๋ณ๊ฒฝํด ์ค๋๋ค.
webSocket.current.onerror = e => {
setServerState(e.message);
};
์๋ฒ๊ฐ ๋ซํ์ ๋๋ ์๋ฒ์ ์ํ๋ฅผ ๋ณ๊ฒฝํด ์ค๋๋ค.
webSocket.current.onclose = e => {
setServerState('Disconnected. Check internet or server.');
};
๋ง์ง๋ง์ผ๋ก useEffect์ ์๋ฒ๋ฅผ ๋ซ๋ ๊ฒ์ ๋ฆฌํดํด ์ค๋๋ค.
return () => {
webSocket.current.close();
};
}, []);
Send a message
์๋์ ๊ฐ์ด JSON์ผ๋ก ๋ ๊ฐ์ฒด๋ฅผ ๋ฌธ์ํ ์์ผ์ ์๋ฒ์ ๋ณด๋ด์ค๋๋ค.
const sendMessage = () => {
let str = JSON.stringify({user: userId, message: messageText});
webSocket.current.send(str);
setMessageText('');
};
View
์๋์ ๊ฐ์ด ๋ทฐ๋ฅผ ๋ ์ด์์ ํด์ค๋๋ค.
return (
<View>
<Text>{serverState}</Text>
<View
style={{
padding: 5,
flexGrow: 1,
}}>
<FlatList
style={styles.list}
contentContainerStyle={{paddingBottom: 50}}
data={serverMessages}
keyExtractor={item => item.id}
renderItem={({item}) =>
item.user == userId ? (
<Text style={styles.myChat}>{item.message}</Text>
) : (
<Text style={styles.otherChat}>{item.message}</Text>
)
}
/>
</View>
<View style={styles.bottomContainer}>
<TextInput
style={styles.input}
placeholder={'Add Message'}
onChangeText={text => {
setMessageText(text);
}}
value={messageText}></TextInput>
<Pressable onPress={sendMessage} disabled={messageText == ''}>
<Text style={styles.send}>Send</Text>
</Pressable>
</View>
</View>
);
};
Source Code