在 React 之前
需要调用 DOM 的 API 来修改 DOM 树的结构从而改变 UI 的展示方式。
React 之后
需要要在业务状态和 UI 状态之间建立一个绑定的关系。
基本概念
用组件的方式描述 UI
在 React 内所有的 UI 都是通过组件去描述和组织的,React 组件是以树状结构组织到一起的,通常会有一个根组件:
- 内置组件:映射到 HTML 节点的组件
- 自定义组件:自己创建的组件,使用时必须以大写字母开头
使用 state 和 props 管理状态
- state:保存状态的机制
- props:父子组件之间传递状态的方式
在函数组件内可以使用useState
这个 Hook 来保存状态,内置组件和自定义组件都可以在使用时把接收的属性 props 作为参数,当这个参数变化时组件也会自动重新渲染。
import React from "react";
function CountLabel({ count }) {
const color = count > 10 ? "red" : "blue";
return <span style={{ color }}>{count}</span>;
}
export default function Counter() {
const [count, setCount] = React.userState(0);
return (
<div>
<CountLabel count={count} onClick={() => setCount(count + 1)} />
</div>
);
}
JSX 语法的本质
JSX 并不是新的模版语言而是一个语法糖,不用 JSX 语法的话也可以使用 React.createElement 来实现。
- JSX 的表达能力等价于 JavaScript;
- 无需学习;
创建应用
npm run create-react-app my-app
cd my-app
npm start
在组件内执行异步请求
需要有数据状态,loading 状态以及错误处理。
在 React 组件中,任何一个 state 发生变化,整个函数组件都会被完全执行一遍。
- 为了避免在组件内重复定义很多函数,可以使用 useCallback 这个 Hook 来缓存回调函数;
- 异步请求逻辑的重用可以利用 Redux 这个全局状态管理框架;
一些思考
React 最打动人的特性是什么?或者说它的最大优点。
- 灵活的 jsx
- 生态强大,核心简单,写法灵活
Hooks(>16.8)
原来的基于 class 的组件完全可以继续使用。
React 组件的本质
就是从 Model 到 View 的映射,这里的 Model 对应的是 state 和 props。
数据绑定:当 Model 发生改变时,函数会重新执行,并且生成新的 DOM 树,然后 React 再将新的 DOM 树以最优的方式更新到浏览器。
为什么会出现 Hooks,原来的 Class 组件有哪些问题?
- React 组件之间不会互相继承,所以没有利用到 Class 的继承特性;
- UI 是由状态驱动的,很少会在外部调用一个类实例,组件的所有方法都是内部调用;
所以这两个 Class 最重要的特性都未使用到,所以用函数去描述State ⇒ View
这样的映射才是最合适的,但是函数组件有没有 State 和生命周期,于是就有了 Hooks。
Hooks 的诞生
函数和对象不同,实例对象不能够在多次执行之间保存状态,所以我们需要一个能够把外部的数据绑定到函数的执行机制。
这个机制就是Hooks,Hooks 就是把某个目标结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或者事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果。
对于函数组件,这个结果就是最终的 DOM 树;对于useCallback
,useMemo
这样的雨缓存相关的组件则是在依赖项发生变化时去更新缓存。Hooks 的结构:
‼️ Hooks 中被钩的对象可以是某个独立的数据源也可以是另一个 Hook 执行的结果,这样就可以达成逻辑复用的效果。
Hooks 带来的最大的好处:逻辑复用
在之前的 React 使用中必须借助高阶组件等设计模式来实现逻辑复用,但告诫组件会产生荣誉的组件节点,所有 Hooks 也大大的简化了逻辑复用。
比如说实现窗口大小的监听,窗口大小是一个外部数据状态,我们可以通过 Hooks 的方式对其进行封装,将其变成一个可绑定的数据源,这样代码会更加简洁直观。
Hooks 的另一个好处:有助于关注分离
能够针对同一个业务逻辑的代码尽可能聚合在一起,在过去的 React 内需要把同一个业务逻辑的代码分散在组件的不同生命周期内。
总结
- React 的开发思想:从 State⇒View 的函数式映射;
- Hooks 解决了 Class 组件存在的代码冗余,难以逻辑复用的问题;