想必大家刚接触React的时候写法都是这样的
第一版(初识React)
const index = () => {
const [number, setNumber] = useState(1);
const updateNumber = () => {
setNumber(number + 1);
};
return (
<>
<div>
number:{number}
<Button
type="primary"
onClick={() => {
updateNumber();
}}>
新增
</Button>
</div>
</>
);
};
可是随着时间
和需求迭代
,代码量的增加发现代码越来越不好维护,那就有了后续的分功能模块组件写,大概就是这样
第二版(组件结构化)
const Header = () => {
return (
<>
我是Header
</>
);
};
const Footer = () => {
return (
<>
我是Footer
</>
);
};
const Index=()=>{
return <>
<Header/>
<Footer/>
</>
}
这么写看起来好像没有问题,但是一旦代入数据流,比如我们自定义一个弹窗,可是我们开启弹窗的按钮又在父组件中,相当于父组件要调用子组件的方法,这时我们就要这样写了
第三版(熟练之路)
const CustomModal =forwardRef((props,parentRef) => {
const [open,setOpen]=useState(false)
const handleOpen=()=>{
setOpen(true)
}
useImperativeHandle(parentRef, () => ({
handleOpen,
}));
return (
<Modal>
我是Header
<Modal/>
);
});
const Footer = () => {
return (
<>
我是Footer
</>
);
};
const Index=()=>{
const modalRef = useRef(null)
const handleOpenModal=()=>{
modalRef.current?.handleOpen()
}
return <>
<Button >查看</Button>
<CustomModal ref={modalRef} />
<Footer/>
</>
}
是不是很啰嗦,对于一个经常开发中后台的我,简直是糟糕透了!
为了解决当前问题,就出现了第四版的写法,复杂的功能逻辑
和UI容器
抽离,UI容器
的所有内容都通过props
传递,对于UI容器的逻辑全部抽离为hooks
,这样其实所有的方法,任意调用和传递,代码如下
第四版(开始创新)
大概就是这个样子,但是随之而来的又一个问题是,父组件的更新会导致所有子组件render
,大家点击新增Add
发现 Footer组件打印了render
,这时候我相信大家就一定会想到用memo
,同样小编也是这么想的,然而并没有什么用
因为memo
只是浅比较,每次render其实都是会生成新的footer变量
,那这其实在大模块下是极其耗费性能的,那该怎么办呢?由此就引发我开发新的功能组件Action
,代码如下
import React, { Fragment } from 'react';
export interface ActionProps<T extends Record<string, any>, K> {
children: (params: T) => React.ReactNode;
useHooks: (options?: K) => T;
options?: K;
}
const Action = <T extends Record<string, any>, K>({ children, useHooks, options }: ActionProps<T, K>) => {
const data = useHooks(options);
return <Fragment>{children(data)}</Fragment>;
};
export default Action;
首先我们要明白一个道理React需要更新UI时,它会重新渲染整个组件树,并通过diffing算法(即虚拟DOMdiff算法)来找出需要更新的地方
,整个组件树,其实只是你的父级。换句话来说,如果我们只想让Header
渲染,其实只需要给Header
加一个父级组件即可,代码如下
第五版(渐行渐远)
这时候大家在点击新增Add
Footer组件就没有任何打印了,我觉得在开发中,只有公共使用的放在最上层,其他的相关hooks只应该放在当前组件的父级。即使后期调整,也会很容易发现受影响的地方。
总结
大家有没有发现整个过程,其实就像一个前端的的成长历程,为什么有的人干了3年和干了1年的差不多,对于这个问题刚开始我也很疑惑🤔。但后来我理解了,就像我的第一版
到第五版
的过程,你可以选择折腾
,也可以选择安逸
,毕竟用第一版
也能开发,老板也不会关心你代码好赖,后期是否好维护也未必和你有关...嗯,突然想到了网上最近很流行的一段话,你本来就是打工的,只是恰巧上了几年学而已😄😄😄
。
最后
到此我的的React最佳实践就结束了,欢迎大家点评、如果觉得不错可以点赞➕收藏哟😌