Created
April 8, 2020 22:07
-
-
Save ozcanzaferayan/ddc542ccab43e34b055ef845819bcbc1 to your computer and use it in GitHub Desktop.
Sample WebSocket usage for React Native App with Typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useState, useEffect} from 'react'; | |
import { | |
StyleSheet, | |
SafeAreaView, | |
FlatList, | |
View, | |
Text, | |
KeyboardAvoidingView, | |
TextInput, | |
TouchableOpacity, | |
} from 'react-native'; | |
export interface Message { | |
user: string; | |
text: string; | |
timestamp: number; | |
} | |
export interface ChatState { | |
messages: Message[]; | |
} | |
const ws = new WebSocket('wss://echo.websocket.org'); | |
const emptyMessage: Message = { | |
user: 'zafer', | |
timestamp: new Date().getTime(), | |
text: '', | |
}; | |
const App = () => { | |
useEffect(() => { | |
ws.onopen = () => { | |
console.log('Websocket opened.'); | |
}; | |
}, []); | |
ws.onmessage = (e) => { | |
console.log(`Received: ${e.data}`); | |
handleReceive(e.data); | |
}; | |
ws.onerror = (e) => { | |
console.log(`Error: ${e.message}`); | |
}; | |
ws.onclose = (e) => { | |
console.log(e.code, e.reason); | |
}; | |
const [message, setMessage] = useState<Message>(emptyMessage); | |
const [chat, setChat] = useState<ChatState>({ | |
messages: [], | |
}); | |
const handleReceive = (text: string) => { | |
const newChat = {...chat}; | |
newChat.messages.push({...emptyMessage, user: 'cpu', text: text}); | |
setChat(newChat); | |
}; | |
const handleSend = () => { | |
console.log('Sent:' + message.text); | |
if (message.text === '') { | |
return; | |
} | |
ws.send(message.text); | |
const newChat = {...chat}; | |
newChat.messages.push({...message}); | |
setChat(newChat); | |
setMessage(emptyMessage); | |
}; | |
const handleChangeText = (e: string) => { | |
setMessage({ | |
text: e, | |
timestamp: new Date().getTime(), | |
user: 'zafer', | |
}); | |
}; | |
const formatTime = (timestamp: number) => { | |
const date = new Date(timestamp); | |
const hours = date.getHours(); | |
const minutes = date.getMinutes(); | |
const hoursText = hours < 10 ? `0${hours}` : hours; | |
const minutesText = minutes < 10 ? `0${minutes}` : minutes; | |
return `${hoursText}:${minutesText}`; | |
}; | |
return ( | |
<SafeAreaView style={styles.container}> | |
<FlatList | |
data={chat.messages} | |
keyExtractor={(item) => item.timestamp.toString()} | |
renderItem={({item}) => ( | |
<View | |
style={{ | |
...styles.messageContainer, | |
...(item.user !== 'zafer' ? styles.messageContainerReceived : {}), | |
}}> | |
<Text style={styles.messageText}>{item.text}</Text> | |
<Text style={styles.messageTime}>{formatTime(item.timestamp)}</Text> | |
</View> | |
)} | |
/> | |
<KeyboardAvoidingView | |
enabled={true} | |
behavior="padding" | |
style={styles.inputContainer}> | |
<TextInput | |
style={styles.textInput} | |
returnKeyType="send" | |
onChangeText={handleChangeText} | |
onSubmitEditing={handleSend} | |
value={message.text} | |
/> | |
<TouchableOpacity style={styles.sendButton} onPress={handleSend}> | |
<Text style={styles.sendButtonText}>Gönder</Text> | |
</TouchableOpacity> | |
</KeyboardAvoidingView> | |
</SafeAreaView> | |
); | |
}; | |
const styles = StyleSheet.create({ | |
container: { | |
margin: 10, | |
flex: 1, | |
justifyContent: 'space-between', | |
}, | |
messageContainer: { | |
alignSelf: 'flex-end', | |
alignItems: 'flex-end', | |
padding: 10, | |
backgroundColor: '#1976d2', | |
borderRadius: 3, | |
marginBottom: 5, | |
flexDirection: 'row', | |
maxWidth: 300, | |
}, | |
messageContainerReceived: { | |
alignSelf: 'flex-start', | |
alignItems: 'flex-start', | |
backgroundColor: '#00796b', | |
}, | |
messageText: { | |
color: '#fff', | |
fontSize: 15, | |
marginEnd: 40, | |
}, | |
messageTime: { | |
color: '#fff', | |
fontSize: 12, | |
opacity: 0.7, | |
marginStart: 10, | |
position: 'absolute', | |
end: 10, | |
bottom: 10, | |
}, | |
inputContainer: {flexDirection: 'row', alignItems: 'center'}, | |
textInput: { | |
flex: 1, | |
borderColor: '#448aff', | |
borderWidth: 1, | |
padding: 10, | |
borderRadius: 3, | |
marginBottom: 20, | |
}, | |
sendButton: {paddingHorizontal: 10, marginBottom: 20}, | |
sendButtonText: {color: '#448aff'}, | |
}); | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great and easy example, thnx for time saving