В React почему функция рендеринга дочернего компонента вызывается дважды? - PullRequest
1 голос
/ 10 апреля 2020

У меня самые простые приложения. Есть родительский <App> компонент и дочерний <MyChildOne> компонент. Оба основаны на классе.

Может кто-нибудь объяснить, , почему React дважды вызывает функцию рендеринга child <MyChildOne>?

Вот мой <App> код:

import React from "react";
import "./App.css";
import MyChildOne from "./MyChildOne.js";

class App extends React.Component {
  render() {
    return (
      <div>
        <MyChildOne />
      </div>
    );
  }
}
export default App;

А вот мой <MyChildOne> код:

import React from "react";

class MyChildOne extends React.Component {
  counter = 0;

  render() {
    this.counter = this.counter + 1;

    console.log(
      "Code has called MyChildOne and this.counter has value: " + this.counter
    );

    return <h1>Hello, {this.counter}</h1>;
  }
}

export default MyChildOne;

Вывод в браузере такой:

Здравствуйте, 1

А вот что регистрируется в консоли:

Код вызвал MyChildOne, и this.counter имеет значение: 1

Код вызвал MyChildOne, и this.counter имеет значение: 2

Так ясно, что React дважды вызывает функцию рендеринга <MyChildOne> - но я не могу понять, почему !!!!

Это бесполезно меня, потому что я хочу передать как props массив вещей от <App> до <MyChildOne>, и я хочу, чтобы <MyChildOne> отобразил, скажем, <h1> для каждого элемента 'вещь' этого массива. Я не хочу, чтобы <h1> отображались дважды!

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

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

Вы должны заметить, что если ваш родительский компонент выполняет рендеринг повторно, то же самое делает и ваш дочерний компонент. Я создал минимальный пример кода, который вы предоставили, чтобы было ясно, что ваша проблема в другом месте. https://codesandbox.io/s/react-example-6ud9d

0 голосов
/ 10 апреля 2020

Я не уверен, почему, но это происходит только в строгом режиме . Я создаю пример проекта с тем же кодом, который вы показали. Попробуйте удалить тег React.StrictMode в файле index. js. Вы увидите, что компонент MyChildOne рендерится только один раз.

Кроме того, если вы хотите установить свойство внутри класса и использовать его внутри метода render , вам следует использовать состояние . Вот так

 state = {
     counter: 0
  }

. И измените состояние следующим образом:

this.setState({counter: this.state.counter + 1});

. Он правильно отрендерит ваш компонент. Но никогда не изменяет состояние внутри render метода; это сломает ваш код.

Если вы не хотите использовать методы состояния и жизненного цикла, не используйте компоненты класса. Вместо этого используйте функциональные компоненты.

...