组件中的条件逻辑与列表渲染 - Conditional Rendering & List Data Rendering
简单来说,组件中经常会出现 if-else
这样的渲染逻辑,比如列表长度为0时不渲染组件,比如在一个大组件中,选择性决定是否渲染某个小部分。有了 if-else
,就一定要出现 JSX 的 { }
标签,原本顺畅的声明式 UI JSX 语法就难看许多。因此,如前所述,为了保证 React 声明式 UI 代码的编写和阅读能力,我们的原则是,使用尽量少的 JSX 语法来处理组件中的 if
渲染逻辑。
经过考察各种各样的方案,只有下面这种方式是我所能勉强接受的、差强人意的解决方案。已经很难看了。
const NewsItem = ({ text, optionalVideoId }) => (
<Text>{ text }</Text>
{ !!optionalVideoId && (
<VideoPlayer id={optionalVideoId} />
) }
)
下面这种很清晰,多出来的 if
JSX 非但不影响效果,反而让组件「读」起来也很顺畅。从阅读上讲比上面的写法好不少,但上面其实是相对比较复杂的 case,无法用这种手法进行处理。
const Login = ({ isLoggedIn, loginMode }) => {
if (isLoggedIn) {
return <Profile loginMode={ loginMode } />
}
return <Login />
}
const Login = ({ isLoggedIn, loginMode }) => {
return isLoggedIn ? <Profile loginMode={ loginMode } /> : <Login />
}
对于列表渲染,RN 中有 FlatList
SectionList
这样内置的类用以渲染列表,但 react 中一般还是需要通过手动的 map
来处理。手动 map 的缺点是太过命令式,需要写一些样板代码,并且最重要的是让 React 的声明式 UI 能力和阅读体验大打折扣。然后我觉得,下面这些常见的逻辑,其实都可以通过封装组件来达到声明式的目的。
- if 条件满足时渲染
- 渲染列表
- 字符串不为空时渲染
<If condition={data.length !== 0}>
<Data />
</If>
<List data={data} renderItem={({ id, title }) => <div>{id}: {title}</div>} />
卧槽,今天发现这些库干的事情就跟我想的一样啊,用来对付简单逻辑,又获得模板声明式的好处,又可以省去测试并依然有信心。然后复杂逻辑就得益于 Vanilla JS 来处理,简直 React 完美的解决方案:
- https://github.com/AlexGilleran/jsx-control-statements
- https://github.com/ajwhite/render-if
- https://github.com/romac/react-if
- https://reactjs.org/docs/conditional-rendering.html
组件的拆分粒度
项目目录结构划分
- functional(actions/reducers/selectors/components/containers)
- duck
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: React 项目的架构和规范
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论