Это хороший способ передать реквизит дочернему компоненту в React?

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

const Parent = ({ foo, bar, baz, myFoo, myBar, myBaz }) => <Child foo={foo} bar={bar} baz={baz} /> (1)

В настоящее время я выяснил альтернативный способ сделать это:

const Parent = ({ foo, bar, baz, myFoo, myBar, myBaz }) => <Child {...{ foo, bar, baz }} /> (2)

ИМО, (2) экономит много времени и сил при наборе текста. Однако:

  1. Есть ли минусы с (2)? Например, считается ли (2) анти-шаблоном React?
  2. Я знаю, что говорить о производительности без измерения плохо, но мне интересно, есть ли какие-либо проблемы с производительностью с (2)?

Обновление 1: я добавил myFoo, myBar, myBaz в реквизиты родителей. Обратите внимание, что я не хочу распространять все реквизиты в дочерний компонент, потому что это считается плохой практикой, которая приводит к ненужным реквизитам в дочернем компоненте.


person Cam Song    schedule 02.04.2020    source источник
comment
Не рекомендуется из-за удобочитаемости reactjs.org/docs/jsx-in-depth. .html#распространенные-атрибуты   -  person Rashomon    schedule 02.04.2020
comment
@Rashomon Что, если моя команда (около 5-6 человек) сочтет его более простым и понятным в использовании? Любые идеи, кроме читабельности?   -  person Cam Song    schedule 02.04.2020


Ответы (3)


Единственным недостатком этого является то, что иногда его трудно понять, используя первый подход, вы делаете код более читабельным и явным. Конечно, если у вас есть какая-то документация по компонентам, например сборник рассказов или что-то, что поможет другим разработчикам понять реквизиты, необходимые компоненту, не имеет значения использование второго подхода (распространение реквизитов), а нужно сделать так, чтобы читабельно, вы должны придерживаться первого (объявляя каждую опору одну за другой).

Проверьте это правило eslint-react-plugin https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md резюмирует, почему лучше использовать первый подход.

person jean182    schedule 02.04.2020
comment
Цените правило. Вам не кажется, что этот {...{ foo, bar, baz }} будет создавать новый объект при каждом рендеринге? Пожалуйста, взгляните на это: правило eslint jsx-no-bind. Интересно, похож ли подход (2) на функцию стрелки в JSX-опоре, которая будет создавать совершенно новую функцию при каждом рендеринге, что может вызвать ненужные повторные рендеры. - person Cam Song; 02.04.2020
comment
Я не думаю, что это работает таким образом, потому что вы передаете реквизиты по-другому, но делаете то же самое, что, например, используя первый подход, я не вижу в этом проблемы, но ИМХО я предпочитаю подход one, я знаю, что его написание может занять больше времени, но читабельность кода намного лучше. - person jean182; 02.04.2020

  1. Почему это считается анти-шаблоном? В конце концов, именно здесь оператор распространения полезен, верно?

  2. Вы не должны заботиться о производительности. В любом случае это будет преобразовано в старый добрый javascript (через babel или что-то подобное). Это просто синтаксический сахар.

person Cristian Riță    schedule 02.04.2020
comment
Вам не кажется, что этот {...{ foo, bar, baz }} будет создавать новый объект при каждом рендеринге? Пожалуйста, взгляните на это: правило eslint jsx-no-bind. Я думаю, что подход (2) примерно такой же, как функция стрелки в JSX-опоре, которая будет создавать совершенно новую функцию при каждом рендеринге, что может привести к ненужным повторным рендерингам. - person Cam Song; 02.04.2020

Вы можете переписать свой код на:

const Parent = (props) => <Child {...props} />

и это на самом деле очень распространено в реакции. Если вам нужны foo, bar или baz где-то еще, вы можете написать это так:

const Parent = (props) => {
  const { foo, bar, baz } = props;
  // do something with foo, bar or baz
  return <Child {...props} />;
}

Возвращаясь к вашим вопросам:

1) Нет, это не анти-шаблон, но вместо этого вы должны использовать описанные выше подходы (до сих пор я никогда не видел кода, похожего на ваш пример, ни в одном проекте). Недостатком может быть то, что вы на самом деле больше не передаете то, что передаете Child, и что вы можете передать больше, чем вам нужно. Например. props из Parent может иметь дополнительное поле, такое как faz, и вы просто передадите его Child, и оно никогда не будет его использовать.

2) Я не могу думать ни о какой серьезной проблеме с производительностью. В своих проектах я использую этот подход очень часто и никогда не замечал проблем с производительностью.

person ysfaran    schedule 02.04.2020
comment
Я обновил свой вопрос. Подробности смотрите в обновлении 1 ниже. Что касается этого, вы можете передать больше, чем вам нужно, причина, по которой я решил переключиться на подход (2), состоит в том, чтобы избежать этого. Вместо <Child {...props} /> я могу ясно видеть и контролировать, какие реквизиты передаются. - person Cam Song; 02.04.2020
comment
Понял! Тогда я лично предпочел бы (1) подход, потому что второй подход выглядит просто странно (как я уже сказал, я никогда раньше его не видел). Или я бы хотя бы сделал const childProps = { foo, bar, baz } а потом <Child {..childProps} /> что тоже не здорово, но ИМХО улучшило бы читабельность хоть немного.. - person ysfaran; 03.04.2020
comment
Чем больше вы к чему-то привыкаете, тем ленивее становитесь. Помимо удобочитаемости, я думаю, что (2) больше подходит для опытных, потому что это экономит много усилий при наборе текста: D. Пожалуйста, подумайте о том, чтобы проголосовать, если вы найдете его потенциальным и полезным! - person Cam Song; 03.04.2020