Как избежать ненужного повторного рендеринга React Component

Я изучаю новые функции React 16.8. Я считаю, что React Pure Component должен автоматически избегать ненужных операций повторного рендеринга.

В следующем примере сам App является компонентом без состояния. Я использую useState для поддержки двух объектов состояния text и nested: {text}.

Есть 3 теста. Первые 2 теста работают. Независимо от того, сколько раз я меняю состояние, никакой операции повторного рендеринга не потребуется.

Теперь третий тест пытается установить состояние text с тем же строковым значением, но с другой ссылкой. Я ожидаю, что ничего не будет перерисовано, но на самом деле <Headline/> будет перерисован.

Должен ли я использовать определенную технику запоминания, чтобы избежать? Я чувствую, что это будет слишком много кода для архивирования. И программист должен быть очень осторожным, чтобы писать качественный код React. ..

class Headline extends React.PureComponent {
  render() {
   const {text} = this.props;
   return <h1>{text} (render time: {Date.now()})</h1>;
  }
} 

const simpleText = 'hello world'

const App = () => {
  const [text, setText] = React.useState(simpleText)
  const [nested, setNested] = React.useState({text: simpleText})
  return (
    <div>
      <Headline text = {text}/>
      <Headline text = {nested.text}/>

      <button onClick = {()=>setText(simpleText)}>
        test 1: the first line should not change (expected)
      </button>

      <button onClick = {()=>setNested({text: simpleText})}>
        test 2: the second line will not change  (expected)
      </button>

      <button onClick = {()=>setText(new String(simpleText))}>
        test 3: the first line will change on every click (why?)
      </button>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector("#app"))

Вот живая площадка в jsfiddle:

https://jsfiddle.net/fL0psxwo/1/

Спасибо, React, ребята, ура!


Обновление 1: Спасибо Денис за упоминание почему ты сделал

Автор указывает несколько очень полезных статей. Я думаю, это может быть очень познавательно для всех. https://medium.com/welldone-software/why-did-you-render-mr-big-pure-react-component-part-2-common-fixing-scenarios-667bfdec2e0f

Обновление 2: Я создал новый хук под названием withDirtyCheck, чтобы мой код автоматически выполнял грязную проверку контента.

import isEqual from 'lodash-es/isEqual';

export const withDirtyCheck = ([getter, setter]) => {
  const setStateIfDirty = (nextState) =>
    setter((prevState) => (isEqual(prevState, nextState) ? prevState : nextState));

  return [getter, setStateIfDirty];
};

Оформить заказ моей последней библиотеки https://github.com/stanleyxu2005/реагировать-einfach

При чем тут PureComponent? Ваши примеры не включают это.

Nicholas Tower 17.07.2019 16:50

Мне нужно пересмотреть свой вопрос. Я имею в виду функциональный компонент без состояния. Я думал, что это чистый классовый компонент. (моя вина)

stanleyxu2005 17.07.2019 16:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
2
183
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что с new оператор вы создаете String Object, который всегда отличается от предыдущего состояния.

'hello world' === new String('hello world') // false, always.
'hello world' === String('hello world')     // true

Проверьте этот пример:

setText(prevState => {

  // Will render
  // const currState = new String(simpleText);

  // Won't render
  const currState = String(simpleText);

  console.info(prevState === currState); // if true, no re-render
                                        // if false, re-render

  return currState;
});

Edit antd-starter

См. В чем разница между строковыми примитивами и объектами String в JavaScript?

Я принимаю вашу точку зрения. Я думаю, что моя главная ошибка в том, что я считаю компонент без гражданства таким же, как и чистый компонент. Но на самом деле они ведут себя совсем по-другому.

stanleyxu2005 17.07.2019 17:30

Но знаете, в большом проекте некоторые люди (вроде меня) могут ошибаться, написав дерьмовый код. Мое желание, даже если я напишу что-то вроде new String(...), я все равно смогу найти проблему на этапе статической проверки или использовать некоторые встроенные / сторонние проверки уровня содержимого, чтобы помочь.

stanleyxu2005 17.07.2019 17:34

Проверьте зачем-ты-рендерил библиотеку.

Dennis Vash 17.07.2019 17:35

Другие вопросы по теме