简体   繁体   English

ReactJS:State 在每次更新时设置回初始值

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

I just began ReactJS and I still have issue understanding states and props.我刚开始 ReactJS 并且我仍然有理解状态和道具的问题。

I'm trying to build a chat app using node.js, React and Socket.io.我正在尝试使用 node.js、React 和 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.我希望 Chat 组件保存由服务器和 messageInput 组件提供的消息列表。

Since the Chat Component will hold the state, I have a constructor that initialize two variables.由于聊天组件将保存 state,因此我有一个初始化两个变量的构造函数。 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.但是,当我从 messageInput 更新这些变量时,组件被重新渲染,导致再次调用构造函数并重新初始化 state。

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.我注意到从服务器检索到的数据不会导致 state 设置为默认值。 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.输入重置 Chat 组件中的状态值,但似乎按预期工作:消息被发送到服务器,并显示给其他客户端。

I think I haven't quite understood how to properly set the state in a component.我想我还不太明白如何在组件中正确设置 state。 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>
        )
    }
}

Re-rendering a component will not cause it's state to be reseted.重新渲染一个组件不会导致它的 state 被重置。 Try changing your handleSubmit function to:尝试将您的句柄提交handleSubmit更改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM