skip to Main Content

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;

2

Answers


  1. 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>
    
    Login or Signup to reply.
  2. 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 });
      }}
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search