TableContainer.js does the common task of fetching data and passing it to a lower component, Table.js, which is a stateless functional component.
currentPage is stored in redux, I did this just to practice redux.
Question 1
Is this all reasonable?
Question 2
I noticed that the component will re-render when it receives a new currentPage and then re-renders again, once the data is loaded. The first re-render is not necessary as nothing changes before data is actually loaded. Should I just live with this or should I implement shouldComponentUpdate() to check if data has changed. Or is that potentially even more costly than the re-render itself?
Question 3
Is using componentDidUpdate() to check if currentPage has changed and then re-load the data a good way of controlling the load process?
Question 4
Is building the URL this way acceptable?
const pageParam = currentPage ? "?_page=" + currentPage : "";
fetch('https://jsonplaceholder.typicode.com/posts/' + pageParam)
TableContainer.js
import React from 'react';
import PropTypes from 'prop-types';
import Table from "../components/Table";
import Pagination from "../components/Pagination";
import {connect} from "react-redux";
import {changePage} from "../js/actions";
const PAGE_COUNT = 10;
const mapStateToProps = state => {
return { currentPage: state.currentPage }
};
const mapDispatchToProps = dispatch => {
return {
changePage: page => dispatch(changePage(page))
};
};
class ConnectedTableContainer extends React.Component {
state = {
data: [],
loaded: false,
};
handlePageChange = page => {
if (page < 1 || page > PAGE_COUNT) return;
this.props.changePage(page);
};
loadData = () => {
this.setState({ loaded: false });
const { currentPage } = this.props;
console.log("load data: " + currentPage);
const pageParam = currentPage ? "?_page=" + currentPage : "";
fetch('https://jsonplaceholder.typicode.com/posts/' + pageParam)
.then(response => {
if (response.status !== 200) {
console.log("Unexpected response: " + response.status);
return;
}
return response.json();
})
.then(data => this.setState({
data: data,
loaded: true,
}))
};
componentDidMount() {
this.loadData(this.props.currentPage);
}
componentDidUpdate(prevProps) {
if (prevProps.currentPage != this.props.currentPage) {
this.loadData();
}
}
render() {
const { loaded } = this.state;
const { currentPage } = this.props;
console.log("render page: " + currentPage);
return (
<div className="container">
<div className="section">
<Pagination onPageChange={ this.handlePageChange } pageCount={ PAGE_COUNT } currentPage={ currentPage }/>
</div>
<div className={ "section " + (loaded ? "" : "loading") }>
<Table data={ this.state.data } />
</div>
</div>
)
}
}
ConnectedTableContainer.propTypes = {
changePage: PropTypes.func.isRequired,
currentPage: PropTypes.number.isRequired,
};
ConnectedTableContainer.defaultProps = {
currentPage: 1,
};
const TableContainer = connect(mapStateToProps, mapDispatchToProps)(ConnectedTableContainer);
export default TableContainer;