ReactJS: запустить функцию при замене реквизита без использования устаревшего componentWillReceiveProps - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть компонент контейнера, который получает номер страницы в качестве реквизита и загружает данные для этой страницы. Я полагаюсь на componentDidUpdate(), чтобы вызвать загрузку, так как componentDidUpdate() срабатывает при изменении pageNumber. Это разумный способ сделать это?

Одна вещь, которую я заметил, - это то, что компонент перерисовывается при получении нового pageNumber, хотя сначала ничего не меняется, а затем он снова перерисовывается после загрузки данных. Первый повторный рендер лишний. Разве я не должен беспокоиться об этом?

Если бы я был действительно обеспокоен, я мог бы использовать shouldComponentUpdate() только для повторного рендеринга, когда data изменяется. (Интересно, может ли эта проверка быть даже более дорогостоящей, чем сама повторная отрисовка?) Однако, если бы я использовал shouldComponentUpdate() и не обновлялся при смене страницы, я бы больше не мог полагаться на componentDidUpdate() для загрузки своих данных.

Значит ли это, что ниже приведен способ сделать это или есть лучший способ?

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;
        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;
        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;

1 Ответ

0 голосов
/ 06 ноября 2018

Прекрасно использовать componentDidUpdate() для запуска загрузки при изменении pageNumber.

Я бы не рекомендовал реализовывать shouldComponentUpdate, вместо этого наследовать от React.PureComponent. Это реализует shouldComponentUpdate для вас путем сравнения реквизита и состояния. Если какой-либо из реквизита и состояние изменятся (поверхностное сравнение), он будет перерисован, иначе нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...