最近有幸参与了公司某运营平台的项目,之前从没用react做过项目的我也第一次真正使用react进行了项目开发。花了两天左右时间学习就开肝了。本文主要对项目中的一些技术点进行总结回顾。
项目搭建和打包
用官方支持的create-react-app创建项目,同时引入@tencent/leah-core插件减小打包体积。首先,在项目入口文件中进行如下修改。
import App from 'components/App';
import * as LeahCore from 'xxx';
LeahCore.renderApp(App);
然后在webpack配置文件中添加externals即可。
externals: {
'react': 'LEAH_React',
'react-dom': 'LEAH_ReactDOM',
'xxx': 'LEAH_Core',
}
leah-core实际上是 react和react-dom 的分包,项目打包时将react剔除,可以减小打包体积。
项目目录结构
- components文件夹中将组件分为dumb和smart,dumb组件只做简单的渲染,没有复杂的逻辑
- configs文件夹中主要是一些常量的定义
- models文件夹中是全局的状态
- utils文件夹中是公用的工具函数
状态管理
状态管理框架选用的是concent框架,官方文档指路。
上节models文件夹中就是用concent管理的全局状态,concent也允许在定义某些组件时,调用configure函数配置模块,整个项目开发过程中,大都是在所需的组件附近进行配置。
ApplyConfig模块自行管理自己的状态,状态定义在model文件夹,该模块中的组件都能共享这些状态。使用过vue的同学马上就会发现computed,watch这两个文件,没错,这两的用法和vue中的computed和watch一样,这就让我这种之前只用过vue的能更快更平滑得上手react。lifecycle文件中定义了一些生命周期,使用起来也特别方便。
再来看看react组件中如何使用这些状态。
import React from 'react';
import { useConcent, SettingsType } from 'concent';
import { DEMO, T_DEMO } from 'configs/c2Mods';
import { CtxM } from 'types/store';
type CtxPre = CtxM<{}, T_DEMO>;
type Ctx = CtxM<{}, T_DEMO, SettingsType<typeof setup>>;
function setup(ctx: CtxPre) {
// optional, mock componentDidMount
ctx.effect(() => {
ctx.mr.changeDesc('componentDidMount some time');
return () => console.log('componentWillUnmount');
}, []);
const ins = ctx.initState({
name: 'demo'
})
ctx.setState({});
return {
ins,
foo: () => console.log('call setttings.foo'),
};
}
function Demo() {
const { state, settings: se, mr } = useConcent<{}, Ctx>({ module: DEMO, setup });
return (
<div>
<p>定义组件所属模块</p>
<p>定义setup</p>
<div>
{state.desc}
{se.ins.name}
<button onClick={se.foo}>call settings.foo</button>
<button onClick={mr.changeDesc}>call mr.changeDesc</button>
</div>
</div>
);
}
export default React.memo(Demo);
整个项目中,reatc组件都是使用的函数组件,引入concent后函数组件不需要使用hook。使用useConcent引入模块状态state和reducer(mr),在组件中可以直接使用和调用。 同时定义setup,setup中返回的对象也可以用useConcent引入为settings。setup函数只会在组件初次渲染前执行一次。
使用ctx.initState可以创建组件内的状态,有一些不需要和其他组件公用的状态就可以在组件内管理。 最后可以发现,我们完全摆脱了react类组件this的束缚,也摆脱了函数组件中各种hook的束缚。
其他
React.memo
React.memo是react的高阶组件,可以通过记忆组件渲染结果的方式提高组件性能。
React.Fragment
React 中的常见模式是为一个组件返回多个元素。Fragments 可以让你聚合一个子元素列表,并且不在DOM中增加额外节点。
useImperativeHandle、forwardRef
useImperativeHandle可以让你在使用ref时自定义暴露给父组件的实例值,以减少暴露给父组件获取的DOM元素属性, 只暴露给父组件需要用到的DOM方法。useImperativeHandle应当与forwardRef一起使用。
文章推荐
推荐一篇适合新手入门react的文章,一杯茶的时间,上手 React 框架开发