So here's the main problem : I open a websocket where I need to read a sessionId in the first coming message to use it for further messages sent. This needs therefore to be done only once.
I have a child component "processMessage" that looks like this :
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>;
}
}
and an "app" parent that open the websocket and get the sessionId component that looks like this (didnt post everything):
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}/>
}
So what's working is that the message is correctly sent with the connection props (socket open) but the sessionId is undefined in the child component because it takes some times to receive the first response of the socket where I get the sessionId but the component doesn't seems to re-render with the new props.
I also try to put in the child component processMessage :
componentWillReceiveProps(nextProps) {
this.setState({ sessionId: nextProps.sessionId});
}
with no success. Am I missing something obvious ?
You should use componentDidMount
lifecycle function as setting state in componentWillMount
doesn't trigger a rerender
and hence the props don't update
From the React docs:
componentWillMount()
componentWillMount()
is invoked immediately before mounting occurs. It is called before render(), therefore setting state synchronously in this method will not trigger a re-rendering . Avoid introducing any side-effects or subscriptions in this method.This is the only lifecycle hook called on server rendering. Generally, we recommend using the
constructor()
instead.
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}
);
}
};
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.