Вы хотите запросить функцию или сообщить об ошибке ?
Просто вопросы
В официальной документации React.Children React вы можете прочитать, что this.props.children
- это «непрозрачная структура данных».
Что именно это значит?
Я думаю, что есть три возможности для прозрачности структуры данных props.children
:
props.children
открыт и четко определен.Если бы это было правильно, то термин «непрозрачная структура данных» был бы совершенно неправильным.
Следовательно, «случай 1» явно не так.
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», очевидно, также не соответствует действительности.
props.children
открыты и четко определены.Это открыло бы возможность того, что один или даже оба примера из «случая 2» верны.
Но тогда это будет означать, что должна быть точная спецификация, какие аспекты props.children
хорошо и открыто определены, а какие аспекты действительно непрозрачны.
Возможно, я что-то упустил в документации React, но я думаю, что это не совсем точно указано, не так ли?
Почему именно props.children
в случае, если есть несколько дочерних элементов (один или больше), всегда не является массивом (как, например, в Preact)? Это сделало бы жизнь намного проще, не так ли?
Заранее большое спасибо за разъяснения.
_ Непрозрачная структура данных_ относится к тому факту, что 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 Спасибо за ответ
Самый полезный комментарий
_ Непрозрачная структура данных_ относится к тому факту, что
children
может быть чем угодно: массивами, фрагментами, отдельными элементами, строковыми литералами и т. Д._React.Children_ содержит несколько методов, которые позволяют вам работать с различными типами
children
_ единым образом_, и это определенно не единственный способ взаимодействия с ними.За исключением того факта, что в JSX есть сокращение,
children
является свойством, как и любое другое. Фактически, вы можете указать это как:Когда React необходимо обновить DOM, было бы намного дороже определить, совпадают ли два массива с одним элементом, чем два примитивных значения (например, строки).
При этом я думаю, что документация React.Children может быть немного расширена, но это проблема, которую нужно зарегистрировать в репозитории responsejs / reactjs.org .
Эта статья может немного прояснить ситуацию, она сделала для меня!