先说说项目结构吧。我这次放弃了直接用create-react-app,而是自己从零搭建。src目录下分了components、pages、hooks、utils这些常规文件夹,但纠结的是到底该按功能模块划分还是按文件类型划分。后来采取了折中方案:通用组件放在components里,业务模块各自建立独立目录,里面包含该模块的组件、样式和逻辑文件。这样既保证了复用性,又避免了组件堆在一起找不到北的情况。
状态管理这块真是让人头大。最开始用useState和useContext简单组合,随着业务复杂度的提升,组件之间传值传得跟蜘蛛网似的。后来上了Zustand,不得不说真香!相比Redux那套繁琐的action、reducer写法,Zustand的API简直太友好了。举个栗子,用户信息状态管理我就这样写:
在组件里使用的时候直接解构需要的状态和方法就行,再也不用写那一大堆connect、mapStateToProps了。
路由管理用的React Router v6,这个版本改动还挺大的。之前用v5的时候还在用Switch,现在全面改用Routes组件。比较坑的是权限验证这块,需要在路由守卫里做文章。我的做法是在最外层包裹一个Auth组件,在里面做登录状态校验,未登录的用户自动跳转到登录页。不过要注意的是,v6版本里Navigate组件的使用姿势和之前的Redirect不太一样,刚开始用的时候老是报错。
性能优化这块水挺深的。最开始我傻乎乎地在每个组件里都用useMemo和useCallback,后来发现完全没必要。经过实践发现,只有在处理大数据量渲染或者确实存在性能问题时才需要考虑使用。比较实用的优化点包括:用React.memo避免不必要的重渲染、合理拆分组件粒度、使用懒加载减少首屏包体积。我特别喜欢用React.lazy配合Suspense实现组件懒加载,代码分割后首屏加载时间直接减少了40%。
自定义Hooks真的是提高代码复用性的神器。我把数据请求、表单处理、定时器这些逻辑都封装成了自定义Hook。比如这个获取数据的Hook:
在组件里调用一行代码就能搞定数据获取和loading状态,再也不用在每个组件里重复写相同的逻辑了。
样式方案我最后选择了CSS Modules,虽然学习成本比styled-components高一点,但胜在性能更好,也不会产生过多的运行时消耗。比较麻烦的是className的命名,得遵循BEM规范才不会乱套。有时候写着写着就出现类似.header__title--active__text这种超长类名,看起来确实有点蠢。
项目打包部署也是个技术活。为了减小打包体积,我配置了webpack-bundle-analyzer分析包大小,把一些不常用的库改成CDN引入。还用了compression-webpack-plugin开启gzip压缩,nginx配置相应的解压规则后,资源加载速度提升非常明显。
说实话,做React项目最深的体会就是:技术选型很重要,但不要过度设计。最开始我总想用最炫酷的技术方案,后来发现简单可靠的方案才是最好的。项目进度卡在某个技术难点上时,该妥协就得妥协,先把功能实现再说,后期再迭代优化也不迟。
最近在尝试用TypeScript重构项目,类型定义确实让代码更健壮了,但各种泛型约束写得头皮发麻。特别是高阶组件的类型定义,有时候一个组件要写十几行类型声明。不过既然选择了TS,跪着也要写完,毕竟后期维护成本能降低不少。
总的来说,React项目开发就是一个不断踩坑、填坑的过程。每个项目做完都能学到新东西,这可能就是前端开发最吸引人的地方吧。不过说真的,下次再做新项目,我可能还是会选择用现成的脚手架工具,自己配置开发环境实在太耗费精力了。