【问题标题】:React child props doesn't update when parent state change当父状态更改时,React 子道具不会更新
【发布时间】:2017-10-03 11:42:13
【问题描述】:

所以这是主要问题: 我打开一个 websocket,我需要在第一条消息中读取 sessionId 以将其用于发送的更多消息。因此,这只需执行一次。

我有一个看起来像这样的子组件“processMessage”:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ChatBot from 'react-simple-chatbot';

export class ProcessMessage extends Component {
  constructor(props) {
     super(props);

     this.state = {
       messages: [],
     };
   }

  componentWillMount() {
    const input = {
      type: 'user',
      sessionId: this.props.sessionId,
      msg: this.props.inputMessage,
    };
    //send message to websocket
    this.props.connection.send(input)

    this.props.connection.onmessage = evt => {
      // add the new message to state
      const msg = JSON.parse(evt.data);

      let responseText = msg.msg;
      this.setState({
        messages : responseText
      })
    };



  }


  render() {
    return <div>{ this.state.messages}</div>;
  }
}

和一个“app”父级打开 websocket 并获取看起来像这样的 sessionId 组件(没有发布所有内容):

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { ProcessMessage } from './components/processMessage.js';

export class App extends React.Component {
  constructor(props) {
    super(props);
    // Assign state itself, and a default value for items


  }
    componentWillMount() {
        const url = 'ws://localhost:4040';

        // this open websocket service
        this.connection = new WebSocket(url);

        this.setState(
          { connection:this.connection }
        );
        var sessionId;
        // listen to onmessage event
        this.connection.onmessage = evt => {

        // add the new message to state
          const msg = JSON.parse(evt.data);
            if (msg.type = "sessionId") {
              sessionId=msg.msg;
              console.log("now received sessionId " +sessionId);
              this.setState(
                { sessionId: sessionId}
              );

            }
        };
  }

  render(){
  return <ProcessMessage sessionId={this.state.sessionId} connection={this.state.connection} inputMessage={this.state.inputMessage}/>
  }

所以起作用的是消息通过连接道具(套接字打开)正确发送,但在子组件中未定义 sessionId,因为它需要一些时间才能接收到我得到 sessionId 的套接字的第一个响应,但是组件似乎没有使用新的道具重新渲染。

我也尝试放入子组件 processMessage :

componentWillReceiveProps(nextProps) {
  this.setState({ sessionId: nextProps.sessionId});  
}

没有成功。我错过了什么明显的东西吗?

【问题讨论】:

    标签: javascript reactjs websocket


    【解决方案1】:

    您应该使用componentDidMount 生命周期函数作为componentWillMount 中的设置状态不会触发rerender,因此道具不会更新

    来自React docs:

    componentWillMount()

    componentWillMount() 在安装发生之前立即调用。 它在 render() 之前调用,因此同步设置状态 此方法不会触发重新渲染。避免引入任何 此方法中的副作用或订阅。

    这是在服务器渲染上调用的唯一生命周期钩子。一般来说, 我们建议改用constructor()

    componentDidMount() {
            const url = 'ws://localhost:4040';
    
            // this open websocket service
            this.connection = new WebSocket(url);
    
            this.setState(
              { connection:this.connection }
            );
            var sessionId;
            // listen to onmessage event
            this.connection.onmessage = evt => {
    
            // add the new message to state
              const msg = JSON.parse(evt.data);
                if (msg.type = "sessionId") {
                  sessionId=msg.msg;
                  console.log("now received sessionId " +sessionId);
                  this.setState(
                    { sessionId: sessionId}
                  );
    
                }
            };
      }
    

    【讨论】:

    • 仍未使用 componentDidMount() 进行更新。我在控制台中正确收到了 sessionId 但 setState 似乎不起作用,因为我在子组件中有一个 console.log(this.props.sessionId) 导致未定义...
    • 问题在于 processMessage 在另一个组件中,这实际上导致了问题,但解决方案实际上是正确的,谢谢!
    猜你喜欢
    • 2020-09-24
    • 2020-11-10
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多