使用分支来重构

时间:2017-03-16 20:11:14

标签: javascript reactjs recompose

我正在重构无状态功能组件,以便使用branch中的renderComponentrecompose

原始组件如下所示:

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.

2 个答案:

答案 0 :(得分:9)

branch返回一个HOC,它接受一个组件并返回一个组件,因此branch(...)是一个HOC而branch(...)(...)是一个组件。

在您的情况下,因为Icon不是组件而是HOC,所以React无法呈现它。要解决此问题,您可以从SvgIcon的参数中移出branch并将其应用于branch(...)返回的HOC,例如:

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

我们将身份函数(a => a)应用于branch的第三个参数。您可以认为身份函数也是一个HOC,它基本上只返回它获得的组件而不再做任何事情。

因为经常使用这种模式,所以branch的第三个参数默认为identity函数。因此,我们可以省略它并使我们的代码更简单:

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

我为这些代码创建了一个jsfiddle。你可以尝试here

答案 1 :(得分:-2)

您也可以使用if语句而不是分支。考虑到你在做一个if语句时遇到了一些困难。

也许是时候重新考虑那个图书馆了?

相关问题