React组件化条件渲染的实现
作者:叶知秋水
背景介绍
React通常搭配jsx使用,jsx把js和视图组合在一起,巧妙地把视图转换成了js模块。但经常写react的应该会看到过很多这样子的代码:
{
tabList.length > 2 ?
<TabBar
tabList={tabList}
tabIndex={tabIndex}
hasLoginBar={showLoginStatus}
tabChange={handleTabChange}
type={'sticky'}
colorTheme={colorTheme}
fontType={'fzlantingyuan'}
/> : ''
}
{
taskList.length || isPreview ?
<p className={styles.rulesText} onClick={() => clickRules()}>规则</p> : ''
}通过一个变量或者一个表达式,控制元素组件的显示和隐藏。从功能上看没什么问题,但从可读性上,却是可斟酌的。
- 过多的括号或者嵌套的括号,难以阅读
- js表达式和元素混合,不直观
这其实都是因为要使用js,增加了括号引起的,那有没有办法不适用括号呢?结合其他框架来看,方案有两种,一种是像Vue一样使用指令,一种是像Solid.js一样使用组件。
由于React 本身并没有内置类似于 Vue.js 自定义指令(v-directive)的功能,所以最理想的还是基于组件去实现。
Solid.js的Show组件
那我们先来看看Solid.js的Show组件。在Solid.js里Show属于控制流组件,其官方介绍如下:
Show 控制流用于有条件地渲染视图的一部分:当 when 为 true 时渲染 children,否则渲染 fallback。它类似于三元运算符(when ? children : fallback),但非常适合模板化 JSX。
import { Show } from "solid-js";
function Show<T>(props: {
when: T | undefined | null | false;
keyed: boolean;
fallback?: JSX.Element;
children: JSX.Element | ((item: T) => JSX.Element);
}): () => JSX.Element;使用方式如下:
<Show when={state.count > 0} fallback={<div>Loading...</div>}>
<div>My Content</div>
</Show>Show 也可以用作将块键控到特定 data model 的一种方式。例如,每当替换 user model 时,都会重新执行该方法。
<Show when={state.user} fallback={<div>Loading...</div>} keyed>
{(user) => <div>{user.firstName}</div>}
</Show>也可以将多个 Show 嵌套使用,用于处理多层级的条件判断。
<Show when={user}>
<Show when={user.isAdmin} fallback={<p>Welcome, regular user!</p>}>
<p>Welcome, admin user!</p>
</Show>
</Show>React的实现
那我们也来实现一个类似效果的组件。
interface ShowProps<T> {
when: T | undefined | null | false;
fallback?: React.ReactNode;
children: React.ReactNode | ((item: T) => React.ReactNode);
}
function Show({ when, fallback = null, children }) {
return when ? children : fallback;
}实现真的是很简单,那么我们来看看前面的例子改写后的形式
<Show when="tabList.length > 2" >
<TabBar
tabList={tabList}
tabIndex={tabIndex}
hasLoginBar={showLoginStatus}
tabChange={handleTabChange}
type={'sticky'}
colorTheme={colorTheme}
fontType={'fzlantingyuan'}
/>
</Show>
<Show when="taskList.length || isPreview" >
<p className={styles.rulesText} onClick={() => clickRules()}>规则</p>
</Show>的确是美观很多,我们也可以增加异步组件的支持
const AsyncShow = ({ when, fallback, children }) => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
Promise.resolve(when).then(result => {
setData(result);
setIsLoading(false);
});
}, [when]);
if (isLoading) return fallback;
return data ? children : null;
};
// Usage
<AsyncShow
when={fetchUserData()}
fallback={<Loading />}
>
{user => <UserProfile data={user} />}
</AsyncShow>结论
在 React 中,通过结合 JSX 和组件化设计,可以实现更加优雅的条件渲染。本文介绍了 Solid.js 的 Show 组件,并借鉴其理念,在 React 中实现了类似的 Show 组件,用于替代传统的三元表达式或逻辑运算符进行条件渲染。这样的实现不仅提升了代码的可读性,还使得 JSX 模板更加直观和简洁。
在日常开发中,倡导大家多学习其他框架的优势,不仅能开拓思维,还能优化现有技术栈的使用方式。多学习并不意味着抛弃当前的技术栈,而是通过吸收优点优化现有代码,甚至推动团队开发的规范升级。学习其他框架的思维方式可以帮助我们跳出惯性,提高对复杂场景的解决能力。
到此这篇关于React组件化条件渲染的实现的文章就介绍到这了,更多相关React组件化条件渲染内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
