Подтвердить что ты не робот

В React.js я должен сделать свой первоначальный сетевой запрос в компонентеWillMount или componentDidMount?

В интерактивных документах рекомендуется создавать начальные сетевые запросы в методе componentDidMount:

componentDidMount() вызывается сразу после установки компонента. Инициализация, требующая узлов DOM, должна идти здесь. Если вам нужно загрузить данные с удаленной конечной точки, , это хорошее место для создания запроса сети. Состояние настройки в этом методе приведет к повторному рендерингу.

Если перед рендерингом компонента вызывается componentWillMount, не лучше ли сделать запрос и установить здесь состояние? Если я делаю это в componentDidMount, компонент визуализируется, выполняется запрос, состояние изменяется, затем компонент повторно отображается. Почему не лучше делать запрос до того, как что-то будет отображаться?

4b9b3361

Ответ 1

Вы должны делать запросы в componentDidMount.

Если компонент componentWillMount вызывается перед рендерингом компонента, не лучше ли сделать запрос и установить здесь состояние?

Нет, потому что запрос не заканчивается к тому времени, когда компонент будет обработан.

Если я делаю это в компонентеDidMount, компонент визуализируется, выполняется запрос, состояние изменяется, затем компонент повторно отображается. Почему не лучше делать запрос до того, как что-то будет отображаться?

Поскольку любой сетевой запрос асинхронный. Вы не можете избежать второго рендеринга в любом случае, если вы не кэшировали данные (и в этом случае вам вообще не нужно будет запускать запрос). Вы не можете избежать второго рендера, уволив его раньше. Это не поможет.

В будущих версиях React мы ожидаем, что componentWillMount будет срабатывать более одного раза в некоторых случаях, поэтому вы должны использовать componentDidMount для сетевых запросов.

Ответ 2

Вы должны сделать запрос в componentDidMount, так как в компоненте componentWillMount не должно быть никаких побочных эффектов. Это прекрасно, чтобы setState в componentWillMount, если вы установилиState в componentDidMount, вы сразу же вызовете вторую повторную визуализацию.

Вы прочтете, что это анти-шаблон (UGHHH) и некоторые линтеры запрещают (eslint-response-plugin), но я бы не стал уделять этому огромное внимание, поскольку иногда это единственный способ взаимодействия с DOM, Вы можете установить свое состояние по умолчанию либо в willMount, либо как свойство метода (state = {}), если вы используете связанный этап babel

Как вы говорите, компонент будет отображаться уже один раз, но это хорошо, потому что вы можете отображать какой-то Loader или любую другую информацию, которую загружает ресурс.

class MyComp extends Component {

    // What I do with stage 0
    state = { mystate: 1 }

    // What you might want to do if you're not 
    // on the experimental stage, no need to do 
    // the whole constructor boilerplate
    componentWillMount() {
        this.setState({ mystate: 1 });
    }

    componentDidMount() {
        dispatch(yourAction());

        // It fine to setState here if you need to access 
        // the rendered DOM, or alternatively you can use the ref
        // functions
    }

    render() {
        if (!this.props.myCollection) return <Loader />

        return (
           <div> // your data are loaded </div>
        )
    }
}

Ответ 3

Вы должны использовать componentDidMount.

Почему не лучше сделать запрос до того, как что-нибудь будет отображаться?

Потому что:

  • Ваш запрос почти наверняка не будет завершен до того, как компонент будет обработан (если не будет рендеринг больших объемов разметки, или вы находитесь в соединении с квантовой связью с нулевой латентностью), и компонент, в конечном счете, должен будет снова выполнить повторную визуализацию, большая часть время
  • componentWillMount также вызывается при рендеринге на стороне сервера (если применимо)

Однако, если бы вы спросили, не лучше ли инициировать запрос в componentWillMount (без фактического обращения с ним на месте), я бы определенно сказал "да" (ES6), и я сам это делаю, чтобы время от времени несколько миллисекунд от времени загрузки:

componentWillMount() {
    // if window && window.XMLHttpRequest
    if (!this.requestPromise) {
        this.requestPromise = new Promise(resolve => {
            // ... perform request here, then call resolve() when done.
        });
    }
}

componentDidMount() {
    this.requestPromise.then(data => ...);
}

Это запустит предварительную загрузку вашего запроса во время componentWillMount, но запрос обрабатывается только в componentDidMount, будет ли он уже завершен или будет продолжаться.