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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема в том, что с 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;
});
См. В чем разница между строковыми примитивами и объектами String в JavaScript?
Я принимаю вашу точку зрения. Я думаю, что моя главная ошибка в том, что я считаю компонент без гражданства таким же, как и чистый компонент. Но на самом деле они ведут себя совсем по-другому.
Но знаете, в большом проекте некоторые люди (вроде меня) могут ошибаться, написав дерьмовый код. Мое желание, даже если я напишу что-то вроде new String(...), я все равно смогу найти проблему на этапе статической проверки или использовать некоторые встроенные / сторонние проверки уровня содержимого, чтобы помочь.
Проверьте зачем-ты-рендерил библиотеку.
При чем тут PureComponent? Ваши примеры не включают это.