#javascript #reactjs #anonymous-types
Вопрос:
Я пытаюсь привести в порядок свой App.js
файл, используя функцию для ввода вложенного массива поставщиков.
Раньше у меня было что-то похожее:
lt;CreditsProvidergt; lt;BundlesProvidergt; lt;ContactsProvidergt; lt;PhoneVerificationProvidergt; lt;PurchaseProvidergt; lt;RanksProvidergt; lt;RoleWizardProvidergt; lt;BasesProvidergt; lt;DepsProvidergt; lt;TitlesProvidergt; lt;UrlsProvidergt; lt;Main /gt; lt;/UrlsProvidergt; lt;/TitlesProvidergt; lt;/DepsProvidergt; lt;/BasesProvidergt; lt;/RoleWizardProvidergt; lt;/RanksProvidergt; lt;/PurchaseProvidergt; lt;/PhoneVerificationProvidergt; lt;/ContactsProvidergt; lt;/BundlesProvidergt; lt;/CreditsProvidergt;
Я создал функцию, которая делает это автоматически:
export function BuildProviderTree(providers) { if (providers.length === 1) { return providers[0]; } const A = providers.shift(); const B = providers.shift(); return BuildProviderTree([ ({ children }) =gt; ( lt;Agt; lt;Bgt;{children}lt;/Bgt; lt;/Agt; ), ...providers, ]); }
Вернувшись, App.js
я загружаю функцию в список поставщиков и добавляю ее в свое приложение.
const Providers = BuildProviderTree( ...[ HeaderBarProvider, CreditsProvider, BundlesProvider, ContactsProvider, PhoneVerificationProvider, PurchaseProvider, RanksProvider, RoleWizardProvider, BasesProvider, DepsProvider, TitlesProvider, UrlsProvider, ] ); lt;NotificationBarProvidergt; lt;NotificationBar /gt; lt;Providersgt; lt;Main /gt; lt;/Providersgt; lt;/NotificationBarProvidergt;
Все работает нормально, однако, когда я использую свои инструменты разработки React для проверки структуры компонентов, я замечаю кучу вложенных анонимных элементов.
Я попытался изменить свою экспортную декларацию, как указано в комментарии, и это не сработало.
Когда я углубился немного дальше, я заметил, что все анонимные элементы исходят от lt;Agt;
элементов функции, в то время как именованные поставщики являются lt;Bgt;
элементами.
Комментарии:
1. Извините, что я опубликовал неправильное изображение в первый раз. Если вы посмотрите на него сейчас, вы увидите, что есть около 10 вложенных элементов, которые просто говорят «Анонимно». Я просто не хочу, чтобы они были в моем дереве элементов.
2. Да, но какие проблемы они вызывают? Разве их нет, когда вы загружаете компоненты обычным способом?
3. Правильно, до того, как я создал функцию для ввода поставщиков, этих анонимных элементов там не было. Я не могу прямо сейчас сказать, что они действительно вызывают конкретную проблему, но я хотел бы устранить ее до того, как проблема будет обнаружена.
4. Попробуйте написать
function BuildProviderTree(providers) {
и в конце страницыexport BuildProviderTree;
вместоexport function BuildProviderTree(providers) {
5. @Giacomo Как способ экспорта функции повлияет на структуру, которую она создает?
Ответ №1:
Анонимные функции — это ваши ({ children }) =gt; ( ... )
функции.
анализ
- После применения первого и второго компонента (
HeaderBarProvider
,CreditsProvider
) новый массив выглядит следующим образом:
[ ({ children }) =gt; ( // lt;-- Anonymous function, new 1st element of array, will be `A` the next time lt;HeaderBarProvidergt; // `A` lt;CreditsProvidergt; // `B` { children } lt;/CreditsProvidergt; lt;/HeaderBarProvidergt; ), BundlesProvider, // lt;-- second element of array, will be `B` the next time ContactsProvider, PhoneVerificationProvider, // ... ]
- После применения предыдущего и третьего компонента (
BundlesProvider
) новый массив выглядит следующим образом:
[ ({ children }) =gt; ( // lt;-- Anonymous (new first element of the array) ({ children }) =gt; ( // lt;-- Anonymous (was previously the first element of the array) lt;HeaderBarProvidergt; lt;CreditsProvidergt; lt;BundlesProvidergt; { children } lt;/BundlesProvidergt; lt;/CreditsProvidergt; lt;/HeaderBarProvidergt; ) ), ContactsProvider, // lt;-- new second element of array PhoneVerificationProvider, // ... ]
возможное решение
Вы должны знать, что происходит во «Время сборки React» (когда создаются компоненты) и что происходит во «время выполнения React» (когда React создает элементы из компонентов).
(термины «время сборки» и «время выполнения» здесь могут быть не совсем правильными)
- ваши анонимные функции, ака. Компоненты React создаются во время «сборки»
- элементы
lt;Agt;
реагируют иlt;Bgt;
создаются во время «выполнения».
С вашим подходом — созданием одного специального компонента (компонента более высокого порядка) для объединения 2 компонентов одновременно, во время «сборки» — вы не можете избежать создания этих функций-оболочек. Вы не можете изменить внешний вид функции (т. Е. компонента), поэтому единственный способ-создать новый компонент, который обернет исходный компонент измененными реквизитами. Этот новый компонент-это анонимная функция.
Что вы можете сделать, так это определить во «время выполнения», как компоненты должны быть преобразованы в элементы. Т. е. вы можете создавать элементы во время выполнения, а не компоненты во время сборки. Таким образом, вам нужен только один специальный, который создает элементы:
export function BuildProviderTreeAtRuntime(originalProviders) { const compose = function(providers, children){ if( providers.length lt; 1 ){ return children; } else { const CurrentComponent = providers.pop(); return compose( providers, lt;CurrentComponent key={'id_' providers.length '_' CurrentComponent.name}gt;{ children }lt;/CurrentComponentgt; ); } } return function ComposedElements({ children }){ // lt;-- only one wrapper function (HOC), which creates all the nested elements const providers = [ ...originalProviders ]; return compose(providers, children); }; }