Избегайте повторного рендеринга в React, вызванном литералом объектов: как это сделать с переменными в объекте? - PullRequest
0 голосов
/ 18 февраля 2019

Я читал в этой статье Реагирует медленно, быстро реагирует: на практике оптимизируем приложения React , что:

Фактически, каждый раз, когда вы передаете объект, буквальный как опорудля дочернего компонента вы нарушаете чистоту.

Хорошо, я понял.Поэтому лучше всего избегать создания переменной с объектом и вставки этой переменной в реквизит, например:

import React from 'react';

const style = { marginTop: 10 };
const AnyComponent = (props) => (
    <div style={style}>
        ...
    </div>
)

Но что, если реквизит стиля зависит от полученной реквизита?Где должен быть объект?Так, например, у меня есть этот компонент:

import React from 'react';

const AnyComponent = (props) => (
    <div style={{ marginTop: props.marginTop }}>
        ...
    </div>
)

Это хорошая практика, чтобы сделать:

import React from 'react';

const style = (marginTop) => ({ marginTop })
const AnyComponent = (props) => (
    <div style={style(props.marginTop)}>
        ...
    </div>
)

[ПРАВИТЬ] Я забыл сказать, что большинство моих компонентов имеют состояние,так что в этом случае, это хорошая идея сделать:

import React from 'react';

class App extends React.Component {

  style = () => ({
    marginTop: this.props.marginTop
  })

  render() {
    return(
      <div style={this.style()}>

      </div>
     )
  }
}

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

Раньше вы не могли делать это в функциональных компонентах (хотя вы могли бы использовать мемоизацию), но теперь с помощью перехватчиков React вы можете сделать что-то вроде этого:

const AnyComponent = (props) => {
    const style = useMemo(() => ({ marginTop: props.marginTop }), [props.marginTop]);
    <div style={style}>
        ...
    </div>
}

И нет, вы можетеНе используйте это:

import React from 'react';

const style = (marginTop) => ({ marginTop })
const AnyComponent = (props) => (
    <div style={style(props.marginTop)}>
        ...
    </div>
)

Поскольку он также создает новый объект при каждом повторном рендеринге AnyComponent, каждый раз вызывая функцию стиля.

0 голосов
/ 18 февраля 2019

Объект может быть запомнен с помощью useMemo hook:

const AnyComponent = (({ marginTop }) => (
    const style = useMemo(() => ({ marginTop }), [marginTop]);
    <div style={style}>
        ...
    </div>
)

Поскольку useMemo предназначен для дорогостоящих вычислений и имеет собственные издержки, это может считаться преждевременной оптимизацией для случая div.

0 голосов
/ 18 февраля 2019

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

import React from 'react';

const AnyComponent = (props) => {
 // if props.marginTop is an object
 const style = props.marginTop;

 return (
    <div style={style}>
        ...
    </div>
)};
...