目录
Hooks 是什么
作用:为函数组件提供状态、生命周期等原本 class 组件中才有的功能,可以理解为通过 Hooks 为函数式组件钩入了 class 组件的特性。
注意:Hooks 只能在函数组件中使用,虽然有了 Hooks,但 React 官方并没有计划从 React 库中移除 class。
小结:有了Hooks函数式组件不能称为无状态组件,因为提供了状态,生命式周期等原本 class 组件中才有的功能
为什么要有 Hooks
它主要可以解决哪些问题?
1.可以解决---组件的状态逻辑复用问题
a,在 Hooks 之前,组件的状态逻辑复用经历了:mixins(混入)、HOC(高阶组件)、render props 等模式。
b,(早已废弃)mixins 的问题:数据来源不清晰;命名冲突。
c,HOC、render props 的问题:重构组件结构,导致组件形成 JSX 嵌套地狱问题。
2.可以解决---class 组件自身的问题
a,选择:函数组件和 class 组件之间的区别以及使用哪种组件更合适。
b,需要理解 class 中的 this 是如何工作的。
c,同一业务的状态和业务逻辑被拆分到不同位置。
3.可以解决---相比于函数组件来说,类组件不利于代码压缩和优化,也不利于 TS 的类型推导。
例如不能把 componentDidMount 压缩成 c 例如写 this 的时候没有提示,因为 this 只有在调用的时候才能确定指向,编写代码期间 TS 是不知道的
Hooks 渐进策略
了解 Hooks 和之前 class 的写法是可以共存的。
Hooks 和现有代码可以同时工作,建议渐进式地使用它们。
不能在 Hooks 组件中,使用 class 组件相关的 API。
还有以前学的知识点还是要用比如
a,JSX:
{}
、onClick={handleClick}
、条件渲染、列表渲染、样式处理等。b,组件:函数组件、组件通讯。
c,React 开发理念:
单向数据流
、状态提升
等。d,解决问题的思路、技巧、常见错误的分析等。
useState 基本使用
作用:为函数组件提供状态和修改状态的方法。
使用的步骤:
1.导入useState函数
2.调用useState函数,并传入状态的初始值
3.然后从useState函数的返回值中,拿到状态和修改状态的函数
import React, { useState } from 'react' const App = () => { const [count, setCount] = useState(0) return ( <div style={{ textAlign: 'center' }}> <h3>计数器:{count}</h3> <div> <button onClick={() => setCount(count + 1)}>+1</button> </div> </div> ) } export default App
需要注意的一些细节
参数:初始状态,比如传入 0 就表示该状态的初始值为 0。
注意:此处的状态可以是任意值(比如,数值、字符串、对象等),注意 class 组件中的 state 必须是对象。
返回值:数组,数组里面包含两个值,状态和修改该状态的方法。
约定:修改状态的方法以 set 开头,后面跟上状态的名称。
useSTate只能写在函数里面
状态 的不可变性表示的是:(修改状态的时候,要使用新的状态替换到旧的状态,而不是直接修改原状态)
useState 另一种写法
在useState里面写回调函数,回调函数的返回值就是状态的最初的值,该回调函数只会触发一次
使用的场景:
a.如果状态需要一个普通数据,也就是一个没有逻辑,不计算的,那么就推荐使用普通的
b. 如果是状态经过一些计算得到的,比如通过for循环循环一万次,那么推荐使用useState(回调函数)
里面的 一些细节是:
如果要为函数组件使用多个状态,那么多次调用 useState 即可,每一次调用返回的
[state, setState]
之间,互不影响。a.它的使用是:只能直接使用在函数式组件里面(其他Hook也是一样)
b.不能直接使用在if/for还有其他函数中,因为if 的条件判断、for 循环的次数、函数的调用与否都可能会影响 hook 的顺序
c,React 是按照 Hooks 的调用顺序来识别每一个 Hook,如果每次调用的顺序不同,导致 React 无法知道是哪一个状态和修改状态的方法。
d,可以通过开发者工具进行查看 React 对 Hook 的管理。
useEffect 副作用介绍
组件和一般函数的副作用是?
a,组件的副作用:对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用,比如手动修改 DOM、数据(AJAX)请求、localStorage 操作等。
b,函数的副作用:如果一个函数修改了其局部环境之外的数据,那么它就被称为有副作用。
关于 useEffect。
作用:当你想要在函数组件中处理副作用(side effect),就要使用 useEffect 了。
useEffect 基本使用
能够在函数组件中操作 DOM(处理副作用)。
执行的机制是:初始化时和数据变化的时候执行
相当于是:class 中的 componentDidMount + componentDidUpdate。
useEffect 依赖说明
能够设置 useEffect 的依赖,只在 count 变化时,才执行相应的 effect。
问题:如果组件中还有其他状态,其他状态更新时,刚刚的 effect 回调(修改标题的操作)也会执行。
默认:函数中的任何状态发生更新,useEffect 的回调函数都会执行。
优化:如何跳过不必要的执行,只有在 count 变化时,才执行相应的 effect。
操作:第二个参数可以传一个数组,表示只有当数组中的选项/依赖项改变时,才会重新执行该 effect。
useEffect 依赖是一个空数组
通过 useEffect 如何让组件只有在第一次渲染后会执行。
useEffect 的第二个参数,还可以是一个空数组([]),表示只有在组件第一次渲染后执行,一般会进行事件绑定、发送请求等。
仅相当于 class 组件的 componentDidMount 钩子函数的作用。
和 useState 一样,一个组件中也可以调用多次 useEffect。
推荐:一个 useEffect 只处理一个功能,有多个功能时,使用多次 useEffect。
useEffect 不要对依赖项撒谎
如果 useEffect 回调函数中用到了某个数据,但是没有出现在依赖项数组中,就会导致一些“Bug”出现(例如 useEffect 回调不会执行)!
useEffect小结
// 触发时机:第一次渲染会执行,任何数据变化导致组件更新时执行,相当于 componentDidMount + ComponentDidUpdate
useEffect(() => {})
// 触发时机:只在组件第一次渲染时执行,相当于 componentDidMount
useEffect(() => {}, [])
// 触发时机:第一次渲染会执行,当 count 变化时会再次执行,相当于 componentDidMount + componentDidUpdate(判断)
useEffect(() => {}, [count])