[SOLVED] REACT Ok, I updated state. where is the re-render?

I am guessing Flux / Redux time??
Can someone confirm this.

I have 2 controls RadioRows (controlling the voting options) and Doughnut (a plugin chart drawer)
These are inside PollDetails
I am handling an update of the vote and can update the state for both the RadioRows and the Doughnut data but the re-render only updates the RadioRows.

Gist of full code file: https://gist.github.com/JohnnyBizzel/841b1a5db64379cc642f02ca2848ac2f

Lines 159-173 is where the state is updated.


            var listLen = updatedList.responses.length;
            for (let i = 0; i < listLen; i++) {
                if (updatedList.responses[i]['response'] == selectedRadio)
                    updatedList.responses[i]['votes'] = totalVotes;
            }
            
            this.setState({
                list: updatedList
            })
            
            // Get doughnut to re-draw chart. (using a data store?)
            var votesSoFar = this.state.list.responses.map(function(rv) { return rv.votes; });
            chartValues.datasets.data = votesSoFar
            // changing state but component does not re-draw
            this.setState({ data : chartValues });

I tried binding on the Doughnut but it isn’t allowed.

Working app is here if you want to look: https://voting-app-bizzel.c9users.io/

Hi @JohnnyBizzel

I believe the problem is that React batches updates to state for performance reasons, so you can’t necessarily rely on setState happening synchronously.

So in your code, when you map over state.list, your actually mapping the old state. Easiest way to fix this is to map the updatedList instead. You could then merge the first call to setState into the second, for readability, like so:

var votesSoFar = updatedList.responses.map(function(rv) { return rv.votes; });
chartValues.datasets.data = votesSoFar
       
this.setState({ 
  data: chartValues,
  list: updatedList
});

Have a look at the setstate docs for more info: https://facebook.github.io/react/docs/react-component.html#setstate.

Hope this helps.

The state is getting updated. The problem seems to be the chart does not re-render the updated state values.

I tried your change which I agree is logical, but it didn’t make a difference.

If you go back home and them back into the Poll, the chart updates.

Okay, I think I’ve found the problem.

The signature of the datasets is that it is an array that contains objects, so all the vote data goes into the first object of that array. The code that updates react is actually setting a second element of the datasets array.

So, when you click a vote, it looks like this:

datasets[
  { data: [oldData] },
  [newData]
]

// What you want it to look like is:
datasets[{
  data: [newData]
}]

So you need to change:

var votesSoFar = this.state.list.responses.map(function(rv) { return rv.votes; });
// this line
chartValues.datasets[0].data = votesSoFar

I think that should do it :slight_smile:

1 Like

Well done sir :blush: :sparkles:

You’re welcome :grin:.

As a side note, I used Reacts developer tools in chrome to figure that out, definitely worth checking out if you use React.

1 Like

Yes, I have them installed but haven’t figured out how to use them apart from viewing the tree.

It gives you a live view of the State and Props for each Component as you click on them. It will also update them as the app is interacted with.

1 Like