Morgan Allen Morgan Allen - 22 days ago 11
Javascript Question

React DOM not re-rendering

My React JS file is below:

The logic behind this:

1.)

CreateTable
renders
CreateColumns
,
CreateRows
, &
ChangeResults


On the first render,
CreateRows
is empty, but once the component mounts, a
fetch()
call is made to update the rows, page re-renders and I have my table

2.)
ChangeResults
component is loaded which creates an input box. State for
num_of_rows
to an empty string (placeholder, not sure if I even need to do this).

When I input some number into the input field and hit click,
onClick
runs
updatePage
, which calls the function
updateRows
(in
CreateTable
), that then changes the state of
people_per_page
. I have the
console.log()
to verify that this is actually happening, and it prints out as expected.

I thought that since
CreateRows
inherits
people_per_page
, and I'm changing the state of
people_per_page
, it would cause a re-render...but nothing is happening.

Can anyone see why that might be?

var CreateTable = React.createClass({
getInitialState: function(){
console.log('initial state loaded')
return {
'table_columns' : ['id','email', 'first', 'last', 'title', 'company', 'linkedin', 'role'],
people_per_page: 34
}
},

updateRows: function(rows) {
console.log(rows)
this.setState(
{people_per_page: rows},
function() {
console.log(this.state.people_per_page)
}
)
},

render: function(){
return (
<div>
<ChangeResults updateRows = {this.updateRows} />
<table>
<CreateColumns columns={this.state.table_columns} />
<CreateRows num_of_rows = {this.state.people_per_page} />
</table>
</div>
)
}
});

var ChangeResults = React.createClass({
getInitialState: function(){
return {
num_of_rows : ''
}

},

handleChange: function(e) {
this.setState({
'num_of_rows' : e.target.value
});
},

updatePage: function(){
this.props.updateRows(this.state.num_of_rows);
},

render: function(){
return (
<div>
Number of people per page: <br />
<input type="text" onChange = {this.handleChange} />
<button onClick={this.updatePage}> Update Page </button>
</div>
)
}

})

var CreateColumns = React.createClass({
render: function(){
var columns = this.props.columns.map(function(column, i){
return (
<th key={i}>
{column}
</th>
)
});

return (
<thead>
<tr>
{columns}
</tr>
</thead>
)
}
});

var CreateRows = React.createClass({
getInitialState: function() {
return {
'people':[],
}
},

componentDidMount: function(){
console.log('componentDidMount running')
this.createRow();
},

createRow : function(){
console.log('starting fetch')
fetch('http://localhost:5000/search', {
method: 'POST',
body: JSON.stringify({
people_per_page: this.props.num_of_rows
})
})
.then(function(response) {
return response.json()
})
.then((responseJson) => {
return this.setState({'people' : responseJson.people })
});
},


render: function(){
var rows = this.state.people.map(function(row, i){
return (
<tr key={i}>
<td>{row['id']}</td>
<td>{row['email']}</td>
<td>{row['first']}</td>
<td>{row['last']}</td>
<td>{row['title']}</td>
<td>{row['company']}</td>
<td>{row['linkedin_url']}</td>
<td>{row['role']}</td>
</tr>
)
})
return (
<tbody>
{rows}
</tbody>
)
}
});


ReactDOM.render(<CreateTable />, document.getElementById('content'));

Answer

In <CreateRows />, componentDidMount is only called for the first render, when the component is 'mounted' on the page. After that, you need to fetch new data in componentDidUpdate or somewhere else in the application.