Почему простой компонент React визуализируется дважды? - PullRequest
3 голосов
/ 01 августа 2020

Я только что начал новый проект create-react-app и заметил, что react дважды отрисовывает компоненты! Моя версия реакции в пакете . json is "react": "^16.13.1"

import React, { useRef } from "react";

const App = () => {
  const renders = useRef(0);
  console.log("renders: ", renders.current++);

  return (
    <div>
      Hello
    </div>
  );
};

Это дает при первом рендеринге:

renders: 0
renders: 0

Теперь, если я добавлю кнопку в состояние приращения, каждое изменение состояния также создает два дополнительных рендера:

import React, { useRef } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const renders = useRef(0);
  console.log("renders: ", renders.current++);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>increment</button>
      <div>count: {count}</div>
    </div>
  );
};

Это приведет к:

//--- initial render
renders: 0
renders: 0
//--- first click
renders: 1
renders: 2
//--- second click
renders: 3
renders: 4
//--- third click
renders: 5
renders: 6

Это нормально или это ошибка в последней версии react?

Ответы [ 2 ]

3 голосов
/ 01 августа 2020

Окей, похоже, я выяснил причину. После проверки index.js я обнаружил следующее:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Похоже, приложение create-react-app теперь включает React.StrictMode, который дважды вызывает определенные методы в режиме разработки (не в производстве).

1 голос
/ 01 августа 2020

В дополнение к обнаруженной вами проблеме StrictMode, я думаю, что когда вы используете ref, он создает побочный эффект, поэтому вам обычно нужно помещать его в useEffect, чтобы предотвратить его отрисовку дважды :

import React, { useState, useEffect, useRef } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const renders = useRef(0);
  useEffect(() => {
    // Every time the component has been re-rendered,
    // the counter is incremented
    console.log("renders: ", renders.current++);
  }); 


  return (
    <div>
      <button onClick={() => setCount(count + 1)}>increment</button>
      <div>count: {count}</div>
    </div>
  );
};

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