Как определить теги компонентов React после сборки в приложении CRA? - PullRequest
0 голосов
/ 17 апреля 2020

Я хотел бы создать и использовать этот компонент в React с ES6:

<Menu>
  <MenuHeader>Hi</MenuHeader>
  <MenuItem>Hello</MenuItem>
  <MenuFooter>End</MenuFooter>
</Menu>

Я определил компонент для обработки этой структуры:

export class Menu extends React.Component {

  render() {
     return (
     <div ...>
        <div ...>
           {HOW TO SELECT HEADER?}
        </div>
        <div ...>
           {HOW TO SELECT ITEM?}
        </div>
        <div ...>
           {HOW TO SELECT FOOTER?}
        </div>
     </div>
  )}

}

Можно итерировать по дочерним элементам и выбирать с помощью type.name при работе на сервере dev без транспиляции:

{ React.Children.map(this.props.children, child =>  { return child.props.type === 'MenuItem' ? <>{ child }</> : '' } ) }          

Но это не работает после сборки it (причина uglify / minify process).

Например, Semanti c UI React хорошо справляется с этим - но он использует интерфейсы и написан на TypeScript, поэтому я не могу использовать его в качестве ссылки.

И еще один вещь (ах Стив :): я не хочу использовать npm eject.

1 Ответ

1 голос
/ 17 апреля 2020

Обычно это делается путем предоставления составным компонентам внутри них возможности отображать своих собственных потомков, а Menu просто отображает children, полученное им, следовательно, сохраняя порядок.

Возможно, вы захотите поделиться состояние вещей, происходящих между заголовком, телом и нижним колонтитулом, поэтому мы добавляем ContextProvider в компонент Menu, чтобы они могли совместно использовать общее состояние.

const rootEl = document.getElementById('root');
const { render } = ReactDOM;
const { createContext } = React;

function MenuHeader({ children }) {
  return (
    <header className="menu-header">
      {children}
    </header>
  )
}

function MenuBody({ children }) {
  return (
    <div className="menu-body">
      {children}
    </div>
  )
}

const MenuContext = createContext();
Menu.Header = MenuHeader;
Menu.Body = MenuBody;

function Menu({ children }) {
  return (
    <MenuContext.Provider value={null}>
      <div className="menu-wrapper">
        {children}
      </div>
    </MenuContext.Provider>
  );
}

function App() {
  return (
    <Menu>
      <Menu.Header>Menu Header</Menu.Header>
      <Menu.Body>Menu Body</Menu.Body>
    </Menu>
  );
}

render(<App />, rootEl);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

Еще один распространенный метод, используемый Frameworks, например Ant.Design, заключается в том, чтобы отображать дочерние элементы и добавлять к ним общие реквизиты (хотя контекст был бы лучшим решением в моем случае. мнение)

...