ReactJS: состояние возвращается к исходному значению при каждом обновлении - PullRequest
0 голосов
/ 18 октября 2019

Я только начал ReactJS, и у меня все еще есть проблемы с пониманием состояний и реквизита.

Я пытаюсь создать приложение для чата, используя node.js, React и Socket.io. На стороне сервера все работает нормально, однако мне сложно отображать данные.

Вот моя проблема: у меня есть приложение с тремя компонентами, организованное следующим образом:

  • Chat | - MessageList | - MessageInput

Я хочу, чтобы компонент Chat содержал список сообщений, который предоставляется сервером и компонентом messageInput.

Поскольку компонент Chatбудет держать состояние, у меня есть конструктор, который инициализирует две переменные. Однако, когда я обновляю эти переменные из messageInput, компонент повторно визуализируется, в результате чего конструктор вызывается снова и состояние повторно инициализируется.

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

Я заметил, что данные, извлеченные изсервер не заставляет состояние быть установленным по умолчанию. Ввод сбрасывает значение состояний в компоненте «Чат», но, похоже, он работает правильно: сообщения отправляются на сервер и отображаются для других клиентов.

Мне кажется, я не совсем понял, какправильно установить состояние в компоненте. Ниже приведен код клиента.

Заранее спасибо!

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>
        )
    }
}

1 Ответ

1 голос
/ 18 октября 2019

Повторная визуализация компонента не приведет к сбросу его состояния. Попробуйте изменить handleSubmit функцию на:

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