2017-10-03 1 views
0

Donc, voici le problème principal: J'ouvre un websocket où j'ai besoin de lire un sessionId dans le premier message à venir pour l'utiliser pour d'autres messages envoyés. Cela ne doit donc être fait qu'une seule fois.Réactualiser les accessoires enfants ne se met pas à jour lorsque le changement d'état parent

J'ai un composant enfant « ProcessMessage » qui ressemble à ceci:

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

et un parent « app » qui ouvrent la websocket et obtenir le composant sessionId qui ressemble à ceci (na pas poster tout):

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

Alors qu'est-ce qui fonctionne est que le message est correctement envoyé avec les accessoires de connexion (socket ouvert) mais le sessionId n'est pas défini dans le composant de l'enfant, car il faut un certain temps pour recevoir la première réponse de la prise où je reçois la sessionId mais le composant ent ne semble pas re-rendre avec les nouveaux accessoires.

J'essaie aussi de mettre dans le composant enfant ProcessMessage:

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

sans succès. Est-ce que je manque quelque chose d'évident?

Répondre

0

Vous devez utiliser la fonction componentDidMount du cycle de vie que la mise en état dans componentWillMount ne déclenche pas un rerender et par conséquent les accessoires ne mettent pas à jour

De l'React docs:

componentWillMount()

componentWillMount() est appelée immédiatement avant le montage. Il est appelé avant render(), donc le réglage de l'état de manière synchrone dans cette méthode ne déclenchera pas un nouveau rendu. Évitez d'introduire des effets secondaires ou des abonnements dans cette méthode.

Ceci est le seul hook de cycle de vie appelé sur le rendu du serveur. Généralement, nous recommandons d'utiliser le constructor() à la place.

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

      } 
     }; 
    } 
+0

Pas encore la mise à jour avec componentDidMount(). J'ai correctement reçu le sessionId dans la console mais le setState ne semble pas fonctionner car j'ai un fichier console.log (this.props.sessionId) dans le composant enfant résultant en un indéfini ... – mehdio

+0

Le problème était que le processMessage était à l'intérieur d'un autre composant qui a causé réellement le problème, mais la solution était en fait juste, merci! – mehdio

+0

Content que vous ayez réussi à résoudre le problème –