Home > Software engineering >  React Native text field doesn't clear up
React Native text field doesn't clear up

Time:08-01

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 });
  }}
/>
  • Related