这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
React的设计思路
响应式编程
(1)状态更新,UI自动更新。
状态更新,UI不会自动更新,需要手动地调用DOM进行更新。
(2)前端代码组件化,可复用,可封装。
欠缺基本的代码层面的封装和隔离,代码层面没有组件化。
(3)状态之间的互相依赖关系,只需声明即可。
UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到"callback Hell"
组件化
- 组件是组件的组合/原子组件
- 组件内拥有状态,外部不可见
- 父组件可将状态传入组件内部
状态归属
- 组件内部拥有私有状态 State。
- 组件接受外部的Props状态提供复用性。
- 根据当前的State/Props,返回一个UI
React Hooks的写法
Hook是 React 16.8 的新增特性,它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
什么是钩子(Hooks)
- 一个特殊的函数,它可以让你"钩入"React的特性
- 消息处理的一种方法,用来监视指定程序
- 函数组件中需要处理副作用,可以用钩子把外部代码"钩"进来
- 常用钩子: useState , useEffect , useContext , useReducer
- Hooks一律使用use前缀命名: useXxx
第一个Hook
useState 是允许你在 React 函数组件中添加 state 的 Hook
import React, { useState } from 'react';
export default function Example() {
// 声明一个新的叫做 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count+1)}>
Cick me
</button>
</div>
)
}
useState方法里面唯一的参数就是初始 state。不同于 class 的是,我们可以按照需要使用数字或字符串对其进行赋值,而不一定是对象。
useState方法的返回值为:当前 state 以及更新 state 的函数。
在 Example 组件内部,我们通过调用 useState Hook 声明了一个新的 state 变量。它返回一对值给到我们命名的变量上。我们把变量命名为 count,因为它存储的是点击次数。我们通过传 0 作为 useState 唯一的参数来将其初始化为 0。第二个返回的值本身就是一个函数。它让我们可以更新 count 的值,所以我们叫它 setCount。
副作用钩子
Effect Hook 可以让你在函数组件中执行副作用操作。
import React, { useState, useEffect } from 'react';
export default function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// 将 document 的 title 设置为包含了点击次数的消息
document.title = `You clicked ${count} times`;
})
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count+1)}>
Cick me
</button>
</div>
)
}
数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用。
将 useEffect 放在组件内部让我们可以在 effect 中直接访问 count state 变量(或其他 props)。我们不需要特殊的 API 来读取它————它已经保存在函数作用域中。Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。
默认情况下,useEffect在第一次渲染之后和每次更新之后都会执行。
Hook规则
Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。
- 只在最顶层使用 Hook
- 只在 React 函数中调用 Hook
遵循此规则,确保组件的状态逻辑在代码中清晰可见。