Автор оригинала: Manas Jayanth.
Чаще, чем нет, я вижу, как правило, написанные так:
class MyComponent extends React.Component { constructor(props) { this.state = { data: props.data /* Where data is an object */ }; }
Гнездовые объекты в состоянии затрудняют обнаружение, если что-то действительно изменилось в ropps.data
Отказ И если мы не проверяем, если данные действительно изменились, мы, возможно, оказываем наш компонент (и, следовательно, детям под ним), без веской причины. Учти это:
class MyComponent extends React.Component { constructor(props) { super(props); } componentDidMount() { setInterval(() => { this.setState({ count: 0 }); }, 1000) } render() { console.log(this.state); // Added this only to illustrate the component behaviour. Avoid console.logs in render() method at all times in production. return (Unrelated div text); } }
Да! this.state.count
даже не ссылается в Render ()
Отказ Тем не менее, при проверке на консоли вы найдете Render ()
Методы, называемые повторением, даже если данные никогда не изменились. Представьте себе такой компонент с сотнями детей. Каждый, запускающий визуализацию абсолютно никакой веской причины.
Просто сделайте вышесказанное в реактивный препарат
- class MyComponent extends React.Component { + class MyComponent extends React.PureComponent {
На этот раз вы не найдете повторяющийся рендеринг. Если это был большой компонент, вы избегали тонн повторных рендеров.
Как это работает
Rect.Purecomponent
делает Простая неглубокая проверка на все его реквизиты и состояние за кулисами Отказ
if (ctor.prototype && ctor.prototype.isPureReactComponent) { return ( !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) ); }
НОВЫЙКУСКИЙ
Проверяет каждое свойство на старом объекте против нового. (Для любопытной партии источник можно найти здесь )
Вернуться к нашей оригинальной проблеме: вложенные объекты в состоянии
Попробуйте выполнить следующее на CodeSandbox Отказ
// Assume App was rendered asThis has already been done for you in the sandbox link above. class App extends React.PureComponent { constructor(props) { super(props); this.state = { data: props.data } } componentDidMount() { setInterval(() => { this.setState({ data: { foo: 1, bar: 2 } }) }, 1000) } render() { console.log(this.state) return ( ); } }Hello CodeSandbox
Start editing to see some magic happen!
Журналы затопляют консоль. Что означает, что рендеринг называли неоднократно.
Теперь сделайте следующие два изменения.
- this.state = { - data: props.data - } + this.state = { + ...props.data + }
и в ComponentDidmount.
- setInterval(() => { - this.setState({ - data: { - foo: 1, - bar: 2 - } - }); - }, 1000); + setInterval(() => { + this.setState({ + foo: 1, + bar: 2 + }); + }, 1000);
А Песочница была создана Для вас уже если вы хотите использовать это. Больше не повторяющихся компонент повторно рендерирует. Подумайте, сколько компонентов повторно предотвращают этот путь, когда данные не изменились
Так что используйте свое государство неглубоко и наслаждайтесь преимуществами Реагировать .purecomponent.