React-defaultProps против параметров ES6 по умолчанию при разрушении (проблемы с производительностью)

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

этот компонент был defaultProps который определил row: false, но мне это не понравилось, потому что defaultProps и в конце файла, что на самом деле затрудняет его просмотр. Таким образом, мы не знаем свойства default. Поэтому я переместил его в объявление функции напрямую и назначил его, используя значение по умолчанию ES6 для параметров.

const FormField = ({
  row = false,
  ...others,
}) => {
  // logic...
};

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

Я считаю, что в этом случае это тривиально. Потому что это логическое, а не объект / массив и поэтому не будет рассматриваться как другое значение во время примирение.


но, давайте теперь посмотрим более продвинутый вариант использования:

const FormField = ({
  input: { name, value, ...inputRest },
  label = capitalize(name),
  placeholder = label,
  row = false,
  meta: { touched, error, warning },
  ...others,
}) => {
  // logic...
};

здесь, я основываю значение placeholder С label, который основан на input.name. Использование ES6 destructuring со значениями по умолчанию для параметров делает все это довольно легко писать / понимать, и это работает как шарм.

а это хорошая идея? А если нет, то как вы это сделаете правильно?

2 ответов


я поговорил с несколькими людьми на канале Discord #reactiflux и фактически получил ответ, который я искал.

есть в основном три варианта использования с компонентами React, и в некоторых из них разрушение парамов повлияет на производительность, поэтому важно понять, что происходит на капоте.

функциональный компонент без состояния

const MyComponent = ({ name = 'John Doe', displayName = humanize(name), address = helper.getDefaultAddress() }) => {
  return (
    <div>{displayName}</div>
  );
};

это функциональный компонент без состояния. Нет никакого состояния, и оно функционально, потому что оно это не Class экземпляр, но простая функция.

в этом случае нет жизненного цикла, у вас не может быть componentWillMount или shouldComponentUpdate или constructor там. И поскольку нет управления жизненным циклом,нет никакого влияния на производительность. Этот код совершенно действителен. Некоторые могут предпочесть обрабатывать значение по умолчанию displayName значение в теле функции, но в конце концов это не имеет значения, это не повлияет на производительность.

нефункциональные без гражданства компонент

(не делайте этого!)

class MyComponent extends React.Component {
    render() {
        const { name = 'John Doe', displayName = humanize(name), address = helper.getDefaultAddress() } = this.props;
        return (
            <div>{displayName}</div>
          );
    }
}

это нефункциональный компонент без состояния. Нет состояния, но оно не "функционально", так как оно class. И потому что это класс, расширяющийся React.Component, это означает, что у вас будет жизненный цикл. Вы можете иметь componentWillMount или shouldComponentUpdate или constructor там.

и, поскольку он имеет жизненный цикл, способ написания этого компонента -плохо. Но почему?

просто put, React предлагает a defaultProps атрибут, чтобы иметь дело со значениями реквизита по умолчанию. И на самом деле лучше использовать его при работе с нефункциональными компонентами, потому что он будет вызываться всеми методами, которые полагаются на this.props.

предыдущий фрагмент кода создает новые локальные переменные с именем name и displayName, а для этого применяются значения по умолчанию


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

если бы я пытался использовать <FormField /> в моем приложении, и мне нужно было посмотреть, какие зависимости имеет этот конкретный компонент, я был бы немного смущен, почему вы создаете параметры, которые основаны на остальные параметры. Я бы передвинул label и placeholder в тело функции, так что это ясный они не являются зависимостями компонентов, а просто побочными эффектами.

что касается производительности здесь, я не уверен, что будет существенная разница в любом случае. Компоненты без состояния на самом деле не имеют "резервного экземпляра", который делают компоненты с состоянием, что означает, что нет объекта в памяти, отслеживающего компонент. Я верю, что это просто чистота. функция передачи параметров и возврата представления.

на той же ноте.. добавление PropTypes поможет с проверкой типа.

const FormField = ({
  input: { name, value, ...inputRest },
  row = false,
  meta: { touched, error, warning },
  ...others,
}) => {
  const label = capitalize(name),
  const placeholder = label,

  return (
    // logic
  );
};

FormField.propTypes = {
  input: PropTypes.shape({
    name: PropTypes.string.isRequired,
    value: PropTypes.string,
  }).isRequired,
  meta: PropTypes.shape({
    touched: PropTypes.bool.isRequired,
    error: PropTypes.bool.isRequired,
    warning: PropTypes.bool.isRequired,
  }).isRequired,
  row: PropTypes.bool.isRequired,
};