我正在重构无状态功能组件,以便使用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.
答案 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语句时遇到了一些困难。
也许是时候重新考虑那个图书馆了?