React之Hook篇
React之Hook篇
useState
什么是state?
在react中,数据不称为data
,而称为state
data
= > state
(状态)
React,其实是一个view library
(view库—只关注视图)
view
=> update
=> 视图的具体状态
state
<=> view
state和视图是相关联的。
视图是某一个状态发生了变化,所以视图要进行相应的更新。
useState()
=> state setState
这个可以解释为,视图需要state
状态。通过useState()
创建了一个状态和设置状态的方法。
react设计理念
react设计理念:一切操作函数化。
在react中,贯彻js—–“函数是一等公民”的理念。
react提供的东西都是朴素的,简单的。
react大部分都是运行时;vue都是编译时的行为。
使用姿势
根据状态变更,有以下俩种:
setXxx(xxx)
简单情况setXxx((x)=>{ return 表达式})
复杂情况
常用写法一:
setXxx(xxx)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32import { useState } from "react";
let initialState = 0;
export default function useStateHook() {
const [count, setCount] = useState(initialState);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+ </button>
</div>
);
}
// 变式
import { useState } from "react";
let initialState = 0;
export default function useStateHook() {
const [count, setCount] = useState(initialState);
function handleClick() {
return setCount(count + 1);
}
return (
<div>
<h1>{count}</h1>
<button onClick={handleClick}>+</button>
</div>
);
}setXxx((x)=>{ return 表达式})
1 | import { useState } from "react"; |
useReducer
这个hook存在的价值
当存在逻辑分支如:+ — * /
=> 都是为了计算count
,也就是count
=>多种操作方案,每一种方案可能有很多地方都需要使用。
reducer
是一个非常好去解决,集成、对状态修改的方案集合的一种方法。
useReducer
是什么
useReducer含义、包含的概念
含义
useReducer
=> 会收集所有操作某一个数据的方案。
1 | const [ count , dispatch ] = useReducer(reducer,0) |
包含的概念
dispath
dispatch
派发器 => 传入的不同操作类型 => 调用不同的逻辑
dispatch({ type, payload })
以下为拿计算器+ - * /
为例:
1 | /** |
useReducer用法
useReducer(reducer,initialState)
接受俩个参数,第一个是reducer
的函数,第二个是initialState
初始值。
1 | const [ count , dispatch ] = useReducer(reducer,0) |
1 | // usReducer |
useEffect
含义
effect
—副作用 => 处理视图状态不相关的逻辑
例如:
- 记时器;
console.log()
;- 数据获取;
- 修改、操作
DOM;
在React
中所有副作用都必须在useEffect()
中执行。
在组件挂载的时候存在一系列生命周期函数。在函数式组件中使用useEffect()
代替类组件中生命周期的函数(简化)。
作用
手动收集依赖;
处理渲染副作用;
使用一个返回值(返回值)去处理副作用清理
代替生命周期函数;
需要根据传递依赖来去代替哪一个生命周期函数
使用
回调函数 + 参数:useEffect(callback,depArr)
第二个参数为:depArr
=> the Array of dependencies
1 | useEffect(() => { |
回调函数callback
中的逻辑是否执行,是依赖depArr
数组里面状态是否改变。因此depArr
一定要在外界保存。
如果第二个参数为
undefined
=> 任何状态改变时,都会重新执行。=> 组件更新的生命周期。以下代码:每当按钮点击时,
count
变更时,useEffect()
都会执行。1
2
3
4
5
6
7
8
9
10
11
12
13export default function useEffectHook() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("useEffect");
});
return (
<>
<div>{count}</div>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</>
);
}如果第二个参数不是一个数组则 => 报警告。
当按钮点击时,会报以下
warning
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// react-dom.development.js:86 Warning: useEffect received a final argument that is not an array (instead, received `object`). When specified, the final argument must be an array.
// Warning: useEffect received a final argument that is not an array (instead, received `object`). When specified, the final argument must be an array.
export default function useEffectHook() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("useEffect");
}, {});
return (
<>
<div>{count}</div>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</>
);
}如果第二个参数是一个数组,且是一个空数组 => 回调只会在函数组件调用时执行一次。(是在根组件执行的时候在执行) =>
componentDidMount
以下执行,只会执行一次。打印一次。
1
2
3
4
5
6
7
8
9
10
11
12
13export default function useEffectHook() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("useEffect");
}, []);
return (
<>
<div>{count}</div>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</>
);
}如果第二个参数是一个有元素的数组 => 元素为状态的话,状态更新,回调重新执行一次。=>
componentDidUpdate
以下代码会先执行一次,当按钮点击时,
count
更新的同时,也会执行打印。1
2
3
4
5
6
7
8
9
10
11
12
13
14export default function useEffectHook() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("useEffect");
}, [count]);
return (
<>
<div>{count}</div>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</>
);
}
清楚副作用
1 | useEffect(() => { |
例子:清楚记时器
1 | export default function useEffectHook() { |
对比Vue中watchEffect
不同 | Vue watchEffect |
React useEffect |
---|---|---|
依赖收集 | watchEffect 自动收集,直接执行我们的回调 |
需要开发者手动收集 |
参数 | 没有第二个参数,第二个参数是watchEffect 自动收集、提供的 |
有第二个参数,需手动追踪依赖 |
清楚副作用 | 回调不返回任何, 清楚通过提供的宏(函数执行) onCleanup(xxx) |
通过回调 return () => { }; 去清楚副作用 |
设计理念 | 观察副作用 | 更多去代替生命周期函数 |
相同点:
都是观察我们的副作用,执行我们的回调