React: Вопросы по "props.children"

Созданный на 26 мая 2018  ·  6Комментарии  ·  Источник: facebook/react

Вы хотите запросить функцию или сообщить об ошибке ?
Просто вопросы

Некоторые вопросы по props.children

В официальной документации React.Children React вы можете прочитать, что this.props.children - это «непрозрачная структура данных».
Что именно это значит?

Я думаю, что есть три возможности для прозрачности структуры данных props.children :

Случай 1: КАЖДЫЙ аспект структуры данных props.children открыт и четко определен.

Если бы это было правильно, то термин «непрозрачная структура данных» был бы совершенно неправильным.
Следовательно, «случай 1» явно не так.

Случай 2: НИКАКОЙ аспект структуры данных props.children не открыт или не очищен.

Это будет означать, что всякий раз, когда вы используете props.children вы ВСЕГДА ДОЛЖНЫ использовать его в сочетании с React.Children поскольку React.Children - единственный (ммм, он действительно единственный?) кто знает о реальной структуре данных props.children .

Но это означало бы, что нельзя разрешать использовать

javascript // This is used almost everywhere (even in the official React documentation) <div>{this.props.children}</div>

ни

javascript // This is often seen with the "Function as child" pattern MyComponent.propTypes = { children: PropTypes.func.isRequired, };

Поскольку оба примера очень распространены, кажется, что «Случай 2», очевидно, также не соответствует действительности.

Случай 3: НЕКОТОРЫЕ аспекты структуры данных props.children открыты и четко определены.

Это открыло бы возможность того, что один или даже оба примера из «случая 2» верны.
Но тогда это будет означать, что должна быть точная спецификация, какие аспекты props.children хорошо и открыто определены, а какие аспекты действительно непрозрачны.
Возможно, я что-то упустил в документации React, но я думаю, что это не совсем точно указано, не так ли?

И последний, но не менее важный вопрос:

Почему именно props.children в случае, если есть несколько дочерних элементов (один или больше), всегда не является массивом (как, например, в Preact)? Это сделало бы жизнь намного проще, не так ли?

Заранее большое спасибо за разъяснения.

Question

Самый полезный комментарий

_ Непрозрачная структура данных_ относится к тому факту, что children может быть чем угодно: массивами, фрагментами, отдельными элементами, строковыми литералами и т. Д.

_React.Children_ содержит несколько методов, которые позволяют вам работать с различными типами children _ единым образом_, и это определенно не единственный способ взаимодействия с ними.

Почему именно props.children в случае, если есть несколько дочерних элементов (один или больше), всегда не является массивом (как, например, в «Preact»)?

За исключением того факта, что в JSX есть сокращение, children является свойством, как и любое другое. Фактически, вы можете указать это как:

<Component children={...}/>

Когда React необходимо обновить DOM, было бы намного дороже определить, совпадают ли два массива с одним элементом, чем два примитивных значения (например, строки).

При этом я думаю, что документация React.Children может быть немного расширена, но это проблема, которую нужно зарегистрировать в репозитории responsejs / reactjs.org .

Эта статья может немного прояснить ситуацию, она сделала для меня!

Все 6 Комментарий

_ Непрозрачная структура данных_ относится к тому факту, что children может быть чем угодно: массивами, фрагментами, отдельными элементами, строковыми литералами и т. Д.

_React.Children_ содержит несколько методов, которые позволяют вам работать с различными типами children _ единым образом_, и это определенно не единственный способ взаимодействия с ними.

Почему именно props.children в случае, если есть несколько дочерних элементов (один или больше), всегда не является массивом (как, например, в «Preact»)?

За исключением того факта, что в JSX есть сокращение, children является свойством, как и любое другое. Фактически, вы можете указать это как:

<Component children={...}/>

Когда React необходимо обновить DOM, было бы намного дороже определить, совпадают ли два массива с одним элементом, чем два примитивных значения (например, строки).

При этом я думаю, что документация React.Children может быть немного расширена, но это проблема, которую нужно зарегистрировать в репозитории responsejs / reactjs.org .

Эта статья может немного прояснить ситуацию, она сделала для меня!

Большое спасибо @danburzo за ваши ответы и пояснения.
После вашего ответа становится ясно, что я совершенно неправильно понял слово «непрозрачный».
Документация React просто хотела сказать, что структура данных props.children - это полностью четко определенный тип объединения и что он варьируется в своем конкретном представлении (как это всегда бывает с типами объединения).

Я только что нашел более старую проблему, посвященную той же теме - интересно, что случилось с этими изменениями?!? (Я открыл проблему на responsejs.org => reactjs / reactjs.org # 914):

https://github.com/facebook/react/pull/6018/files/91223423410f107ff83a8a6ce3158c488247292f?short_path=ef51787#diff -ef51787305cfed62f6f564284762d4de

Тем не менее, я хотел бы еще раз задать второй вопрос:
Почему "props.children" НЕ является массивом, если есть ровно ОДИН дочерний элемент (это действительно кажется нарушением принципа наименьшего удивления, если вы не знаете фона => если имя - "children" или "items" или "жетонов" вы обычно ожидаете коллекцию)?
Неужели из соображений производительности? Я действительно не могу понять, что вычисление "checkResult" ниже занимает столько времени:

const
  child1 = ...,
  child2 = ...,
  child1IsArray = Array.isArray(child1),
  child2IsArray = Array.isArray(child2),

  checkResult = child1IsArray && child2IsArray
     && child1.length === 1 && child2.length === 1
     && child1[0] === child2[0]; 

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

Я рад, что смог помочь вам с первой частью вашего вопроса! К сожалению, относительно того, почему одиночные дочерние элементы не представлены в виде массива из одного элемента, у меня нет точного ответа. Тем не менее, я пытался указать на то, что вы все равно можете передать одного дочернего элемента в качестве обычной опоры (а не сокращенного JSX), факт, который я случайно скрыл своей гипотезой о том, что это связано с производительностью.

@danburzo Еще раз спасибо за ваш ответ.

Ммм, честно говоря, я надеялся, что, возможно, кто-то из команды React вспомнит настоящую причину этого дизайнерского решения ...
Потому что действительно есть некоторые тонкие проблемы с обработкой опор детей в React.
Например, спросите новичка в React, будут ли компоненты Test1 и Test2 в следующем примере вести себя одинаково (вы, как профессионал React, знаете, что ответ - «нет» => Test2 предупредит DEV о недостающих ключах, а Test1 - нет - но разве это то, чего вы ожидали бы, будь вы новичком?!?)

const
  h = React.createElement,
  Test1 = () => h('div', null, h('br'), h('br')),
  Test2 = () => h('div', { children: [h('br'), h('br')] });

ReactDOM.render(
  h('div', null, h(Test1), h(Test2)),
  document.getElementById('container')
);

Между прочим: если Test2 будет разрешен, это будет иметь некоторые незначительные преимущества в производительности, если вы реализуете некоторые замены createElement - например, некоторую функцию гиперкрипта.

Другой пример: спросите новичка в React, как будет выглядеть «children: PropTypes ....», если требуется, чтобы все дочерние элементы удовлетворяли определенному условию. Думаю, ответить будет непросто (по крайней мере, для новичка).

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

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

Потому что действительно есть некоторые тонкие проблемы с обработкой опор детей в React.

Обычно мы не рекомендуем использовать явную опору children . Большинство пользователей также используют JSX вместо прямого вызова React.createElement , поэтому упомянутые вами проблемы обычно не являются проблемой.

@aweary Спасибо за ответ

Была ли эта страница полезной?
0 / 5 - 0 рейтинги