Получить все дочерние компоненты, используя компонент React высшего порядка - PullRequest
2 голосов
/ 20 мая 2019

Моя цель - добавить обработчик кликов для всех элементов привязки с href, который ссылается на внешний домен.

Это мой компонент:

import React from 'react';
import LinkWrapper from './LinkWrapper'

function ComponentWithLinks() {
  return (
    <div>
      <div>
        <ul>
          <li>
            <a href="/">internal link</a>
          </li>
          <li>
            <a href="http://example.com/external">external link</a>
          </li>
        </ul>
      </div>
      <div>
        <p>
          <a href="http://google.com">another external link</a>
        </p>
      </div>
    </div>
  );
}

const wrapped = LinkWrapper(ComponentWithLinks)

export default wrapped;

А это моя обертка:

import React from 'react';

function LinkWrapper(WrappedComponent) {
  return class extends React.Component {
    render() {
      return <WrappedComponent {...this.props} />;
    }
  }
}

export default LinkWrapper;

Дети вложены сколь угодно глубоко.

Как мне перехватить каждую из них, чтобы я мог прикрепить к ней обработчик щелчков?

1 Ответ

0 голосов
/ 21 мая 2019

Хорошо, этот беспорядок, мы будем использовать React.Children API для обхода всех реагирующих элементов и React.createElement для добавления свойств (в данном случае onClick).

const injectToChildren = (children, addOnClickToAnchors) =>
  React.Children.map(children, addOnClickToAnchors);

const injectToAnchor = child =>
  React.cloneElement(child, { onClick: () => console.log('New Click') });

const addOnClickToAnchors = child => {
  const children = child.props.children;

  // Recursion end condition
  if (!children) return;

  const isAnchor = child.type === 'a';

  return isAnchor
    ? injectToAnchor(child)
    : {
        ...child,
        // Recursion step
        props: { children: injectToChildren(children, addOnClickToAnchors) }
      };
};

function ComponentWithLinks({ children }) {
  // Map every children recursively
  return injectToChildren(children, addOnClickToAnchors)
}

function App() {
  return (
    <ComponentWithLinks>
      // All kinds of children components
    </ComponentWithLinks>
  );
}

Edit Inject All Tree

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...