简体   繁体   中英

React.js cycle of life when updating data

What I want :

I have a node.js server, a captor and a react.js client. Each time the captor detect something it sends a message by socket.io to my node server which return data to my React website (in JSON).

I want that each time my client React.js received new data from my server, it automatically refresh the specified component (generally charts).

My Code :

Index.jsx

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {data: []};
    socket.on('dataCards', function (cards) {
      this.state = {data: cards};
    });
  }
  render () {
    return (
      <div className="container-fluid">
        <NavBarTop />
        <div className="row">
          <NavFilter />
          <div className="col-sm-7-5 col-md-7-5" id="mainPage">
            <DataAnalytics />
            <CardsList data={this.state.data} />
          </div>
          <Interventions />
        </div>
      </div>
    );
  }
}
render(<App />, document.getElementById('container'));

cardlist.jsx :

import React from 'react';

class Card extends React.Component {
  constructor(props) {
    super(props);
  }

  rawMarkup() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return { __html: rawMarkup };
  }

  render() {
    return (
      <div className="ticket">
        <h2 className="cardUID">
          {this.props.uid}
        </h2>
        <span dangerouslySetInnerHTML={this.rawMarkup()} />
      </div>
    );
  }
}

export default Card;

I'm not very familiar with React.js cycle of life. Unfortunately render is called before that data arrived to my client. So when cardlist.jsx is called props.data is null.

I don't know how to structure my code to do what I want...

Anybody can help me ?

You won't have data in render the first time through. Just throw up a loading indicator or something in the meantime. You should do your data loading in either componentDidMount or componentWillMount.

You need to use setState function in order to update your state. It would trigger rerender of your component. Use "this.state = something" only to set initial state of your component.

socket.on('dataCards', (cards) => {
    this.setState({data: cards});
});

And you probably would like to use componentWillMount or componentDidMount lifecycle hooks to listen to socket.io and stop listening upon componentWillUnmount hook.

componentDidMount() {
    socket.on('dataCards', (cards) => {
        this.setState({data: cards});
    });
}

componentWillUnmount() {
    socket.off('dataCards');
}

Also your Card component looks weird to me. But I have no detailed information about your code to give some advice.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM