React component not re-rendering on state change

brandonhilkert :

I have a React Class that's going to an API to get content. I've confirmed the data is coming back, but it's not re-rendering:

var DealsList = React.createClass({
  getInitialState: function() {
    return { deals: [] };
  },
  componentDidMount: function() {
    this.loadDealsFromServer();
  },
  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });

    this.setState({ deals: newDeals });
  },
  render: function() {
    var dealNodes = this.state.deals.map(function(deal, index) {
      return (
        <Deal deal={deal} key={index} />
      );
    });
    return (
      <div className="deals">
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Amount</td>
              <td>Stage</td>
              <td>Probability</td>
              <td>Status</td>
              <td>Exp. Close</td>
            </tr>
          </thead>
          <tbody>
            {dealNodes}
          </tbody>
        </table>
      </div>
    );
  }
});

However, if I add a debugger like below, newDeals are populated, and then once I continue, i see the data:

  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });
    debugger
    this.setState({ deals: newDeals });
  },

This is what's calling deals list:

var Gmail = React.createClass({
  render: function() {
    return (
      <div className="main">
        <div className="panel">
          <DealsList person={this.props.person} />
        </div>
      </div>
    );
  }
});
Michelle Tilley :

That's because the response from chrome.runtime.sendMessage is asynchronous; here's the order of operations:

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (3) sometime in the future, this function runs,
  // but it's too late
  newDeals = deals;
});

// (2) this is called immediately, `newDeals` is an empty array
this.setState({ deals: newDeals });

When you pause the script with the debugger, you're giving the extension time to call the callback; by the time you continue, the data has arrived and it appears to work.

To fix, you want to do the setState call after the data comes back from the Chrome extension:

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (2) sometime in the future, this function runs
  newDeals = deals;

  // (3) now you can call `setState` with the data
  this.setState({ deals: newDeals });
}.bind(this)); // Don't forget to bind(this) (or use an arrow function)

[Edit]

If this doesn't work for you, check out the other answers on this question, which explain other reasons your component might not be updating.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

React not re-rendering on state change

React-Redux : Child component not re-rendering on parent state change when using connect() in child

React child component not re-rendering on state change

React-native Redux Component not re-rendering on state change with boolean value

Parent component unnecessarily re-rendering child on parent state change

React-redux component is not re-rendering after state change

React is not re-rendering on state change

React UseContext change not re-rendering component

React: Child component not rendering on parents state change

react component not re-rendering on state change from parent component firebase

State change not re-rendering component

React component not re-rendering on state change using setState

Component isn't re-rendering after state change in reducer

Map of React Components not re rendering on State Change

React is not re-rendering on state and props change

Parent React component not re-rendering on change state in child using react hooks;

my component is not re-rendering on state change react native

React Component Re rendering

React Hooks: how to avoid re-rendering of component on another state change?

One Component not re-rendering on state change while other is not

React function component state not re-rendering?

React functional component not re-rendering with state change

Component not re-rendering after change in an array state in react

React functional component is not re-rendering on state change

How to stop child component re-rendering on parent state change?

React app not re-rendering on state change

React component not re-rendering on component state change

why child components div in react is not re rendering even though child component re renders at state change

React Component Not Re-Rendering From Redux State Change