I am developing an messaging app using react-native
and socket.io
. when I send the message the message gets delivered successfully but the text on the text-field doesn't clear up and I get the error message Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, the componentWillUnmount method
.
import React from 'react';
import { View, StyleSheet, Text, FlatList, TextInput } from 'react-native';
import { Button } from 'react-native-paper';
import { io } from 'socket.io-client';
import colors from '../config/colors';
class Messages extends React.Component {
constructor(props) {
super(props);
this.state = {
chats: [],
message: '',
};
}
componentDidMount() {
const socket = io('http://localhost:1000');
socket.on('chat', (chats) => {
this.setState({ chats: [...this.state.chats, chats] });
});
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.chats}
renderItem={({ item }) => <Text>{item.message}</Text>}
keyExtractor={(item) => item.id.toString()}
/>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
onChangeText={(text) => {
this.setState({ message: text });
}}
/>
<Button
onPress={() => {
const socket = io('http://localhost:1000');
socket.emit('chat', {
message: this.state.message,
});
this.setState({ message: '' });
}}
>
Send
</Button>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.black,
},
input: {
backgroundColor: colors.text,
//color: colors.text,
height: 40,
flex: 1,
borderRadius: 20,
},
inputContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
});
export default Messages;
CodePudding user response:
Try async
keyword with componentDidMount
async componentDidMount() {
//existing code
}
and while defining the states, it's adviced to use null
instead of ""
this.state = {
chats: [],
message: null,
};
hence similarly, set it null after the message has been sent
this.setState({ message: null })
even use functions instead of multiline on button trigger
sendMessage = async() => {
const socket = io('http://localhost:1000');
socket.emit('chat', {
message: this.state.message,
});
this.setState({ message: null });
}
<Button onPress={this.sendMessage}>
Send
</Button>
CodePudding user response:
Data binding in React can be achieved by using a controlled input. A controlled input is achieved by binding the value to a state variable and a onChange event to change the state as the input value changes. you should add a prop value={this.state.message}
to your text component to achieve desired results.
<TextInput
value={this.state.message}
style={styles.input}
onChangeText={(text) => {
this.setState({ message: text });
}}
/>