Использование ветки из recompose

Я рефакторинг функционального компонента без сохранения состояния для использования branch и renderComponent из recompose.

Исходный компонент выглядит так:

const Icon = props => {
  const { type, name } = props
  let res
  if (type === 'font') {
    return (<FontIcon name={name} />)
  } else if (type === 'svg') {
    res = (<SvgIcon glyph={name} />)
  }

  return res
}

Компонент с веткой выглядит так:

const isFont = props => {
  const { type } = props
  return type === 'font'
}

const FontIconHoC = renderComponent(FontIcon)
const SvgIconHoC = renderComponent(SvgIcon)

const Icon = branch(isFont, FontIconHoC, SvgIconHoC)

Icon.propTypes = {
  type: string,
  name: string
}

export default Icon

Я пытаюсь визуализировать компонент, используя:

<Icon name='crosshairs' type='font' />

В результате ошибка выглядит следующим образом:

invariant.js:44Uncaught Error: Icon(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

person vamsiampolu    schedule 16.03.2017    source источник


Ответы (2)


branch возвращает HOC, который принимает компонент и возвращает компонент, поэтому branch(...) — это HOC, а branch(...)(...) — это компонент.

В вашем случае, поскольку Icon - это не компонент, а HOC, React не может его отобразить. Чтобы исправить это, вы можете переместить SvgIcon из аргументов branch и применить его к HOC, возвращаемому branch(...), например:

const Icon = branch(
  isFont,
  FontIconHoC,
  a => a
)(SvgIcon)

Мы применяем функцию тождества (a => a) к третьему аргументу branch. Вы можете думать, что функция идентификации также является HOC, которая в основном просто возвращает компонент, который она получает, и больше ничего не делает.

Поскольку этот шаблон используется очень часто, третий аргумент branch по умолчанию используется для функции идентификации. В результате мы можем его опустить и сделать наш код проще:

const Icon = branch(
  isFont,
  FontIconHoC
)(SvgIcon)

Я создал jsfiddle для этого кода. Вы можете попробовать это здесь.

person wuct    schedule 19.03.2017

Вы также можете просто использовать оператор if вместо ветки. Учтите, что у вас только что возникли некоторые трудности с тем, что делает оператор if.

Может пора пересмотреть эту библиотеку?

person Bradford Medeiros    schedule 14.07.2017
comment
цель вопроса заключалась в том, чтобы выяснить, как использовать ветку из документации. это исследовательская работа, которую я делаю для себя. Хотя я согласен с тем, что ветка может иметь ограниченное использование, есть определенные утилиты от recompose, такие как withHandlers и withReducer, которые мне очень нравятся. Это действительно помогло мне при рефакторинге гигантских компонентов React в более мелкие компоненты без сохранения состояния. - person vamsiampolu; 14.07.2017
comment
Я рекомендую вам рассмотреть возможность использования шаблонов, которые поощряет перекомпоновка, без обязательного использования самой библиотеки. - person Bradford Medeiros; 27.07.2017
comment
@BradfordMedeiros Это ужасный ответ. Проблемы с библиотекой не должны означать, что вы должны пересмотреть библиотеку. Цель перекомпоновки — сделать код более читабельным и тестируемым, что он и делает. - person Martin Dawson; 20.08.2017
comment
Есть дипломатия, а есть идея позвать императора за то, что он не носит никакой одежды. Подумайте об этом --> вышесказанное буквально, буквально оператор if. И он спросил о переполнении стека, как использовать обертку, это чертовски простой оператор if. Просто посмотрите на источник: github.com/acdlite/ recompose/blob/master/src/packages/recompose/ Какой замечательный способ написать x ? у: з. Очень слаб. - person Bradford Medeiros; 29.08.2017