ReactJS: State is set back to initial value at each update

LRobert

I just began ReactJS and I still have issue understanding states and props.

I'm trying to build a chat app using node.js, React and Socket.io. Everything is working fine on the server side, however, I have some hard time displaying the data.

Here's my issue: I have an app with three components, organized as below:

  • Chat |- MessageList |- MessageInput

I want the Chat component to hold a list of messages, which is provided by the server and the messageInput component.

Since the Chat Component will hold the state, I have a constructor that initialize two variables. However, when I update these variables from the messageInput, the component is re-rendered, causing the constructor to be called again and the state re-initiliazed.

class Chat extends React.Component{
    constructor(){
        super()
        this.state = {
            messageList: [],
            username:null
        }
    }

I have noticed that the data retrieved from the server does not cause the state to be set to default. Input resets the value of the states in the Chat component, but seems to be working has intended: messages are send to the server, and displayed to the other clients.

I think I haven't quite understood how to properly set the state in a component. You'll find some of the client code below.

Thanks in advance!

const io = require('socket.io-client')
const socket = io.connect('localhost:4242')

class Chat extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            messageList: [],
            username:null
        }
    }

    componentDidMount(){
        if (this.state.username == null){
            var user = prompt("Enter username:")
            this.setState(
                {username: user}, function(){
                    socket.emit('new_client', this.state.username)
                    this.addMessage({
                        text: this.state.username + " has entered the chat",
                        sender:"server",
                        timestamp: Date.now()})
                    })
        }
        socket.on('broadcast', data =>{
            let newList = this.state.messageList.concat([data])
            this.setState({messageList: newList})
        })

    }
    addMessage(object) {
        const array = this.state.messageList
        let newList = array.concat([object])
        this.setState({
            messageList: newList})
    }

    sendMessage(messageString){
      const message = {sender: this.state.username,
            text: messageString,
            timestamp: Date.now()}
        socket.emit('message', message)
        this.addMessage(message)
    }

        render(){
            return(
                <div className="app">
                <MessageList
                    messageList={this.state.messageList}
                    username={this.state.username}
                 />
                <MessageInput
                    sendMessage={i=> this.sendMessage(i)}
                />
                </div>
            )
        }
}

class MessageList extends React.Component{
//USED TO DISPLAY CHAT MESSAGES, WORKS WELL
}


class MessageInput extends React.Component{

    constructor(props){
        super(props)
        this.state = {
            message:''
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }


    handleChange(event){
        this.setState({
            message: event.target.value
        })
    }

    handleSubmit(event){
        this.props.sendMessage(this.state.message)
        this.setState({
            message:''
        })
    }
    render(){
        return(
            <form
               onSubmit={this.handleSubmit}
               className="send_message_form">
               <input
                   onChange={this.handleChange}
                   value={this.state.message}
                   placeholder="Input a new message"
                   type="text"/>
           </form>
        )
    }
}
Grabofus

Re-rendering a component will not cause it's state to be reseted. Try changing your handleSubmit function to:

handleSubmit(event){
    this.props.sendMessage(this.state.message)
    this.setState({
        message:''
    })
    event.preventDefault(); // So the page won't refresh
}

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

redux update state value without changing initial state

$.each index initial value

How to set the initial value of useState with the value of another state set in a useEffect hook?

Animate CSS keyframes back to initial state

single-tenant logic app how to set an Initial state for each workflow

How to set my database back to the initial values

Getting helper method to run on initial update of state

How to update my initial state in redux reducer

Reactjs state not render to update the DOM

React call back on set state

React call back on set state

How to set initial state of rnn as parameter in tensorflow?

Set value of prop in child component and pass value back to state of app.js, react

set state in a function not working - reactJs

ReactJs: How to pass the initial state while rendering a component?

ReactJS | Cannot update during an existing state transition

Update State of a Component from Another in ReactJS

Update state with Reactjs DatePicker doesn't work

What is the best place to update the state in ReactJS?

ReactJs update state from axios api data

ReactJs update state from axios api data

reactJs update state object without overwriting the object

how to update parent state in child component and pass to parent state back?

value of useState not being set on initial render

how to set initial(default) value in dropdownButton?

How to set initial value of ForeignKey dynamically in CreateView?

ReactJS: Best way to check state values and update render based on state?

cant update context state when using hooks with a complex object to set providers value

How do we set FSM Initial State in VHDL?