我是靠谱客的博主 外向毛衣,这篇文章主要介绍React Hook,现在分享给大家,希望可以做个参考。

 1. 为什么使用 hook

class 组件中的 this 难以理解,且 class 不能很好的压缩,并且会使热重载出现不稳定的情况。

所以 hook 就为解决这些问题而来:

避免地狱式嵌套,可读性提高。

函数式组件,比 class 更容易理解。

class 组件生命周期太多太复杂,使函数组件存在状态。

解决 HOC 和 Render Props 的缺点。

UI 和 逻辑更容易分离

2. Hook的一些API

我来介绍一下,hook的一些常用的api

2.1 useState

使用状态    

复制代码
1
const [data,setData] = useState("默认值")

注意事项 1:不可局部更新

如果 state 是一个对象,能否部分 setState?

答案是不行,因为 setState 不会帮我们合并属性

那么 useReducer 会合并属性吗?也不会!

因为 React 认为这应该是你自己要做的事情

注意事项 2:地址要变

setState(obj)如果 obj 地址不变,那么 React 就认为数据没有变化,不会更新视图

useState 接受函数

复制代码
1
const [state, setState] = useState(() => {return initialState}) //该函数返回初始 state,且只执行一次

2.2 useReducer

用来践行 Flux/Redux 思想

一、创建初始值 initialState

二、创建所有操作 reducer(state, action)

三、传给 userReducer,得到读和写 API

四、调用写({type:"操作类型"})

如何代替 Redux

一、将数据集中在一个 store 对象

二、将所有操作集中在 reducer

三、创建一个 Context

四、创建对数据的读取 API

五、将第四步的内容放到第三步的 Context

六、用 Context.Provider 将 Context 提供给所有组件

七、各个组件用 useContext 获取读写 API

2.3 useContext

全局变量是全局的上下文

上下文是局部的全局变量

使用方法

一、使用 C = createContext(initial) 创建上下文

二、使用 <C.Provider> 圈定作用域

三、在作用域内使用 useContext(C)来使用上下文

2.3 useEffect

副作用

对环境的改变即为副作用,如修改 document.title

但我们不一定非要把副作用放在 useEffect 里面

实际上叫做 afterRender 更好,每次 render 后执行

用途

一、作为 componentDidMount 使用,[ ] 作第二个参数

二、作为 componentDidUpdate 使用,可指定依赖

三、作为 componentWillUnmount 使用,通过 return

四、以上三种用途可同时存在

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 作为 componentDidMount 使用,[] 作为第二个参数 useEffect(() => {     console.log("第一次渲染执行这句话"); }, []); // [] 里面的变量变化时执行 => 不会执行 // 作为 componentDidUpdate 使用,可指定依赖 n useEffect(() => {     console.log("n变化时执行这句话"); }, [n]); // n 变化时执行 useEffect(() => {     console.log("任何一个state变化时都会执行"); }); // 作为 componentDidUpdate 使用,可指定依赖 n useEffect(() => {     const timer = setInterval(() => {         console.log("hi");     }, 1000);     return () => {         setTimeout(() => {             window.clearInterval(timer);         }, 10000);     }; },[]);

特点

如果同时存在多个 useEffect,会按照出现次序执行

2.4 useLayoutEffect

布局副作用

useEffect 在浏览器渲染完成后执行

useLayoutEffect 在浏览器渲染前执行

特点

useLayoutEffect 总比 useEffect 先执行

useLayoutEffect 里的任务最好影响了 Layout

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* useLayoutEffect比useEffect先执行 */ function App2() {     const [n, setN] = useState(0)     const onClick = () => {         setN(i => i + 1)     }     //执行顺序打印出 2、3、1     useEffect(() => {         console.log(1)     })     useLayoutEffect(() => {         console.log(2)     })     useLayoutEffect(() => {         console.log(3)     })     return (         <div className="App">             <h1>n: {n}</h1>             <button onClick={onClick}>Click</button>         </div>     ); }

经验

为了用户体验,优先使用 useEffect (优先渲染)

2.5 useMemo

特点

第一个参数是 () => value

第二个参数是依赖 [m, n]

只有当依赖变化时,才会计算出新的 value

如果依赖不变,那么就重用之前的 value

这不就是 Vue 2 的 computed 吗?

注意

如果你的 value 是一个函数,那么你就要写成 useMemo(() => x => console.log(x))

这是一个返回函数的函数

是不是很难用?于是就有了 useCallback

2.6 useCallback

用法

useCallback(x => console.log(x), [m]) 等价于

useMemo( () => x => console.log(x), [m])

2.7 forwardRef

useRef

可以用来引用 DOM 对象

也可以用来引用普通对象

forwardRef

props 无法传递 ref 属性

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function App(){     const buttonRef = useRef(null)     return (         <div>             <Button ref={buttonRef}>按钮</Button>             {/* 控制台报错:                     Warning: Function components cannot be given refs.                 Attempts to access this ref will fail.                 Did you mean to use React.forwardRef()?             */}         </div>     ) } const Button = (props) => {     console.log(props) // {ref: undefined, children: "按钮"}     return <button {...props} /> }

实现 ref 的传递:由于 props 不包含 ref,所以需要 forwardRef

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
import React, {forwardRef, useRef} from 'react'; function App(){     const buttonRef = useRef(null)     return (         <div>             <Button ref={buttonRef}>按钮</Button2>         </div>     ) } const Button = forwardRef((props, ref) => {     console.log(ref)  //可以拿到ref对button的引用,forwardRef仅限于函数组件,class 组件是默认可以使用 ref 的     return <button ref={ref} {...props} />; })

最后

以上就是外向毛衣最近收集整理的关于React Hook的全部内容,更多相关React内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部