1

I am using mqtt to receive some data and I would like to add that data directly to a dictionary.

My probably naive way to add the data to the dictionary is the following:

this.client.on('message', (topic, message) => {
  this.state.mqttMessage[topic] = message.toString();    
})

I also tried the following:

  this.setState(prevState => ({
    mqttMessage: {
        ...prevState.mqttMessage,
        topic: message.toString()
    }
  }))

But that adds the keyword "topic" to the dictionary.

The above line seems to generate the following warning as well:

Do not mutate state directly. Use setState()  react/no-direct-mutation-state

Later I would like to show what was received above, using this code:

  render() {
    console.log(this.props.mqttMessage)

return (
  <div>
      test1: {this.props.mqttMessage["test1"]} <br/>
      test2: {this.props.mqttMessage["test2"]} <br/>
      test3: {this.props.mqttMessage["test3"]} <br/>
  </div>
);

}

But the problem is that objects don't seem to get updated directly, I need ti refresh the page in order for the content to kick in. I guess I am not using the setState properly. The proper way of doing what I am trying to do would be appreciated.

Below is the whole code:

import React, { Component } from 'react';

import Button from 'react-bootstrap/lib/Button';
import Tab from 'react-bootstrap/lib/Tab';
import Tabs from 'react-bootstrap/lib/Tabs';

import 'rc-slider/assets/index.css';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mqttMessage: {}
    }

    this.mqtt = require('mqtt')
    this.client = this.mqtt.connect('mqtt://192.168.10.100:9001')

    this.client.on('connect', () => {
      this.client.subscribe('test1')
      this.client.subscribe('test2')
      this.client.subscribe('test3')
    })
    this.client.on('message', (topic, message) => {
      this.state.mqttMessage[topic] = message.toString();    
    })

  }

  render() {
    return (
      <div className="App">
        <Tabs defaultActiveKey="profile" id="uncontrolled-tab-example">
          <Tab eventKey="home" title="Home">
            <PostMessage client={this.client} />
          </Tab>
          <Tab eventKey="seats" title="Seats">
            <SeatPage mqttMessage={this.state.mqttMessage} client={this.client} />
          </Tab>
        </Tabs>

      </div>
    );
  }
}


class PostMessage extends React.Component {

  sendMessage = (e) => {
    e.preventDefault();
    this.props.client.publish('demo/test', 'My Message');
  }

  render() {
    return (
      <Button onClick={this.sendMessage}>
        Send Message
      </Button>
    );
  }
}


class SeatPage extends React.Component {

  sendMessage = (e, topic, message) => {
    e.preventDefault();
    this.props.client.publish(topic, message);
  }

  render() {
    console.log(this.props.mqttMessage)

    return (
      <div>
          test1: {this.props.mqttMessage["test1"]} <br/>
          test2: {this.props.mqttMessage["test2"]} <br/>
          test3: {this.props.mqttMessage["test3"]} <br/>
      </div>
    );
  }
}

export default () => (
    <App />
);
1

1 Answer 1

2

In react you shouldn't change state object directly. You should rather use setState method.

Something like below should do the trick.

this.client.on('message', (topic, message) => {
  this.setState({
     ...this.state,
     mqttMessage: {
         ...this.state.mqttMessage,
         [topic]: message
     }
  })    
})
Sign up to request clarification or add additional context in comments.

2 Comments

I almost tried that but with topic instead of [topic]. Can you explain the difference?
New to javascript? :D if you use 'topic': 'some topic value', the string 'topic' is your key. If you use [topic]: 'some topic value', topic is a variable and it's value is your key

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.