前端框架-React
组件是 React.js 的基础
next.js 默认使用 page.tsx 作为入口
1 | / -> app/page.tsx |
React Hooks
useState 回调函数只有在第一次渲染的时候才会执行。
1 | const [state, setState] = useState(() => { |
父子组件的通信
请记住单向数据流。
- 父组件 -> 子组件:通过 props 属性传递
- 子组件 -> 父组件:通过 props 传递函数,触发父组件中的状态更新
在 vue 中父组件将 props 传递给子组件,子组件如果想要更改父组件中的值是通过抛出一个事件$emit
通知父组件v-on
来进行的。和原生 DOM 事件不一样,组件触发的事件没有冒泡机制。你只能监听直接子组件触发的事件。平级组件或是跨越多层嵌套的组件间通信,应使用一个外部的事件总线,或是使用一个全局状态管理方案。双向数据传递的方案可以使用 v-model
。
react hooks 类似 vue 组合式函数。
组件
类组件和函数式组件
按照组件的定义方式可以分为类组件和函数式组件。现在推荐使用函数式组件,代码写起来简洁,并且兼容类组件的所有特性,类组件是历史产物。
- 纯函数:函数组件更容易编写纯函数(即相同的输入总是产生相同的输出,没有副作用)。
- 不可变性:通过 Hooks(如 useState)管理状态时,状态更新是不可变的,这有助于避免副作用。
- 组合性:函数组件可以更容易地组合和复用。
React Hooks 是 React 16.8 引入的革命性特性,它允许你在函数组件中使用状态(state)和其他 React 特性,而无需编写 class 组件。
客户端组件和服务端组件
组件默认是服务端组件,除非使用 use client
。服务端组件是在服务器完成渲染的,不支持浏览器 API(window, document),不支持 React 状态和副作用。适合静态内容和数据密集型页面(在服务端组件完成数据库查询,不会被加载到客户端);而客户端组件适合强交互和需要浏览器 API 的页面。
server components 才能是 async 的
服务端组件是不是又回到了 JSP 时代?
服务端组件并不是简单地回到 JSP/PHP 的时代,而是在现代前端生态的基础上,结合了服务器端渲染的优势。它提供了以下改进: 组件化开发:基于 React 的组件化模式;性能优化:支持代码拆分、懒加载、边缘计算等现代性能优化技术。
构建工具
Vite:vue 作者开发,包含 2 部分:
- 开发服务:服务于开发环境,ESM + HMR
- 构建指令:服务于生产环境,用 Rollup 打包
传统打包工具例如 webpack 需要提供一个 entry,在启动的时候需要加载所有,而 ESM 打包器这种概念类似于按需加载,启动速度和更新速度都比较快。Vite 将模块区分为依赖和源码 2 类,提升开发服务启动时间。
依赖:开发时不会变动纯 js,Vite 会使用 esbuild 预构建(golang 编写)依赖。
源码:通常为 JSX,CSS,Vue SFC 等,经常会被编辑,需要转换,基于路由拆分。
Vite 以原生 ESM 方式提供源码,让浏览器接管打包工作。
Next.js
全栈框架 Next.js + Remix 已经占了 React 生态的 50%,官方的 create-react-app 已经很久没有进行维护了。主流的前端框架都有一个对应的全栈框架 meta framework。Vue + Nuxt, servlet + servletKit。前端的未来就是全栈。前端必须要用 js,SSR 框架必须使用 nodejs(php,java 无法实现)。
ServerAction
编写的函数是运行在服务端的,但是我们可以在客户端直接调用(就像调用本地函数一样),省去了在服务端对函数去包装 API 的这个过程。use server
标注的函数。
Router
Parallel Routies:@
插槽,并行关系,例如:导航
Intercepting Routies: 在当前页面下打开其他页面的路由,但是不会跳离当前页面的上下文
Api Router Handler
Loading
文件路由
app 是应用根目录,app 目录下的每个目录代表一级路由
上图中的 src/app/dashboard/app/[app]
最后的 [app]
表示动态路由(可以被变量替换)
layout 是可以被继承的,page 只有在当前对应的路由下才会生效。
Tailwind CSS
React 生态中一种常见样式的写法就是 Css in JS,最具有代表性的就是 stypled components,Emotion.js,Pandajs(几乎无运行时js),特性:灵活、模块化;缺点是性能(动态计算,插入节点),SSR 不友好(服务端渲染 html,需要在客户端进行样式合并,会有各种情况发生)
另一种解决方案是原子化 css,最小化样式文件(只有用到才会打包),随着项目复杂度的提升,最终用到的 css 文件的增量会越来越少。突出问题类名过长,难以阅读。
提供了一些语义化的实用的类名:bg-black/[.05]
的意思:
bg-black
:这部分表示背景颜色为黑色/
:斜杠表示透明度(opacity)[.05]
:方括号是任意值语法,允许任何自定义值,.05
表示透明度 5%
冒号:
有特殊的含义,用于表示修饰符。
dark:
暗色模式hover:
鼠标悬停sm:
响应式断点,小屏幕focus:
聚焦active:
激活
hover:bg-red-500
鼠标悬停的时候变为标准红色。数值的取值是 50-950,较小的数值趋向于白色,较大的值趋向于黑色,一般 200 才开始有明显变化。
滤镜
基础滤镜
blur-{amount} - 模糊效果
1 | blur-sm /* 小模糊 */ |
brightness-{amount} - 亮度
1 | brightness-50 /* 50%亮度 */ |
contrast-{amount} - 对比度
1 | contrast-0 /* 无对比度 */ |
颜色处理
grayscale - 灰度
1 | grayscale-0 /* 原色 */ |
sepia - 褐色
1 | sepia-0 /* 原色 */ |
invert - 反转
1 | invert-0 /* 原色 */ |
UI 组件
Shadcn = Radix UI + Tailwind Css 样式,无需进行安装,直接生成到项目中,作为源码的一部分。
最佳实践
- key 可以帮助 React 识别列表中的每个元素,优化渲染性能,避免状态混乱。使用唯一标识符作为 key,避免使用索引。
- 使用 uppy 进行文件上传。