«Анонимные» HTML-элементы, добавленные при консолидации поставщиков React

#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; ( ... ) функции.

анализ

  1. После применения первого и второго компонента ( 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,  // ... ]  
  1. После применения предыдущего и третьего компонента ( 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);  }; }