我们在做后管类项目时,常常会和表单打交道,编辑状态和创建状态常常会令人头疼,看样例,有图有真相。
这是一个VUE
的项目中的一个创建套餐和编辑套餐的页面1707行!,下面样式部分还没算上。
页面使用isEditing
属性来区分编辑还是新建,它也是付出了很多。
这就是典型的编辑、新建页面加逻辑在一把梭啊,因为这个页面在我入职的时候就已经有了,所以只能动上面的代码,我是一动不敢动啊,就怕搞出bug
了。每一次有需求要动的时候,我都在祈祷不要动套餐部分,不要落到我头上 (但是还是没有那么幸运啊,有幸改了一次,很难受,一点不让我乘凉),1707行真的很难改啊!!!
好消息是,它走上正轨了,不用我们动了!
所以,在新的项目中我写的部分,文件通常都在200多行,基本不会过400行,只要颗粒度一细,文件大小自然就下来了。但是有时候也不能过度的要颗粒度。
今天来谈一下经典的React设计模式容器组件和展示组件,这种模式有助于提高代码的可读性和可维护性,也是分分钟解决上面的屎山代码。也是我在项目中经常使用的一种方式,可以将逻辑和UI
分别统一起来一起处理。
正文
什么是容器组件和展示组件
展示组件(Presentational Components) :
- 主要负责
UI
的渲染。 - 通常是无状态的函数组件。
- 通过
props
接收数据和回调函数。 - 尽可能避免使用状态和逻辑。
容器组件(Container Components) :
- 主要负责业务逻辑和数据处理。
- 通常是有状态的组件。
- 通过
props
将数据和回调函数传递给展示组件。 - 处理与
Redux
或其他状态管理工具的交互。
如何使用容器组件和展示组件
不使用容器组件和展示组件的代码是什么样子,不用再演示了吧,自己去看看项目中1000多行的屎山代码就可以了。接下来步入正题。
大致代码就是下面这个样子,外面就是容器组件
,主要负责业务逻辑和数据处理。InfoShow
就是展示组件
,只负责UI
的渲染,通过props
接收数据和回调函数改变数据。同理要改变容器组件
里面的什么展示什么不展示,是否disable
等等,都可以通过props
传递状态。
export default function Index() {
const [info, setInfo] = useState<Info>({
name: '',
time: '',
peopleList: [],
});
useEffect(() => {
//如果是编辑状态,则从服务器获取数据
}, []);
return (
<>
<InfoShow
info={info}
handleChange={(data: Partial<Info>) => {
setInfo({ ...info, ...data });
}}
/>
</>
);
}
还可以使用hook
进一步的优化。
如何通过 React 钩子取代容器组件
自 React 16.8.0 以来,借助函数组件和钩子构建和开发组件变得更加容易。
我们将利用这一能力,用钩子替换容器组件
。可以进一步的优化代码,使Index
不再是容器组件
,而是起到一个桥梁的作用。真正起容器组件
作用的是useInfo
,进一步的细化颗粒度。
//useInfo.ts
import React, { useCallback, useEffect, useState } from 'react';
import { Info } from '../type';
export default function Index() {
const [info, setInfo] = useState<Info>({
name: '',
time: '',
peopleList: []
})
const handleChange = useCallback((data: Partial<Info>) => {
setInfo(prev => ({ ...prev, ...data }))
}, [])
useEffect(() => {
//如果是编辑状态,则从服务器获取数据
}, []);
return {
info,
setInfo,
handleChange
}
}
export default function Index() {
const { info, handleChange } = useInfo();
return (
<>
<InfoShow info={info} handleChange={handleChange} />
</>
);
}
结语
感兴趣的可以去试试,一个很不错的Reac
t设计模式。