十分钟学会 React Hooks
一、为什么要使用Hooks
我们都知道React 为我们提供了两种创建组件的方式, 函数组件和类组件,函数组件是一个普通的JS函数, 可以接收一个props对象并返回一个React。而类组件不仅有props 还有自己的状态、生命周期,从而在使用时有些复杂组件变的很难理解; Hooks 就是让纯函数中也可以有自己的状态,解决一些类组件不好用的地方
比如:class组件中我们必须去绑定事件处理器、相互关联的代码逻辑被进行了拆分(componentDidMount里面你定义了一个定时器,你需要在componnetWillUnmount中清除)
什么是Hook?
Hooks是react 16.8 以后的新特性, 可以让你在不编写class时使用state以及React 新特性。
Hook 是一些可以让你在函数组件钩入 React State 和 生命周期的函数, 不能在class 中使用 ,比如useState就是在函数组件中钩入State的Hook
二、语法上看class和Hooks区别
一个计数器的小例子;当你点击按钮的时候,计数器的值会增加
一个简单的有状态组件
我们看一下使用Hooks 的版本
三、基础: useState、useEffect
1、useState如何声明
useState
数组解构
const [count, setCount] = useState(0);
解构出来的变量直接使用,setCount是去改变count的值
不解构
const _useState= useState(0) // useState()函数会返回两个值;
let count = _useState[0]
let setCount = _useState[1]
调用useState时发生了什么?
定义了一个变量,可以叫做任意的名字,这只是函数调用时保存变量的一种方式,useState是一种新的方法,与this.state 的功能完全相同,一般来说,函数退出后变量会消失,而state中的变量会被state 保存,setState去改变值时做的是合并状态后返回一个新的状态, 但是setCount是直接替换老状态返回新状态
useState需要哪些参数?
需要的唯一参数就是初始的state,不同于class的是 class类组件中的state必须是个对象,而hooks 是没有限制的
useState的返回值?
返回值就是[count, setCount],我们声明一个count 的state 变量,把它设置为0,通过setCount 去改变
2、useState如何使用(读取、更新)
我们看一下上面的例子,用户读取时 直接用count就可以了,再也不用像以前的组件使用this.state.count, 非常简单明了
更新时 ,当用户点击按钮的时候,我们调用了setCount 函数, 这个函数接收的参数是修改后的新状态值,更改后React就会重新渲染我们的组件,并且使用的是我们更新后的状态, 那大家会不会有个问题,组件就是一个普通的函数,为什么它可以记住之前的状态
为什么Hook可以记住状态, 而不是每次初始化?
通常来说我们在一个函数中声明了变量,当函数运行完成后,这个变量也就销毁了
注意:
一个组件里面如果有多个状态,所以我们可以在一个组件中多次使用state、useState, 定义不同的变量, 在hooks里面是怎么知道哪个state对应的是哪个useState, 靠的是hooks的调用顺序,只要Hook的调用顺序在多次渲染里保持一致,React 就能正确地将内部的state和对应的Hook 进行关联
所以hoooks是不能在条件语句中使用,我们要把hooks 写在函数的最外层
2、useEffect
我们在生命周期里面都是做的副作用的事情(和函数业务逻辑关联不大,比如请求数据),在React里面就是effect 去执行这个动作
useEffect 就相当于class组件里面的生命周期,componentDidMount,componentDidUpdate, componentWillUnmount有相同作用,当你调用useEffect时, 就是告诉React在完成对Dom的更改后运行你的函数
我们要注意几点:(使用Hooks)
第一,React首次渲染和之后的每次渲染都会调用一遍传给useEffect的函数,也就是组件每一次渲染都会执行useEffect函数,而在class组件我们会用两个生命周期函数分别表示首次渲染和更新后渲染;
第二,useEffect 是异步的
如何在useEffect函数里请求异步数据
(如果处理不好,有时候会出现无限请求的问题)
useReact是如何区分生命钩子
生命周期函数的调用主要是通过useEffect 的第二个参数[props.source]去控制的,有以下几种情况:
1、第二个参数如果不传,每次都会调用Effect函数,也每次都会调用返回的函数
2、第二个参数为[],Effect函数只会在初始化时调用一次,返回的函数也只会在组件卸载时调用一次
3、第二个参数有值时,则会监听数组里的值, 当该值发生变化时才会调用Effect 函数和返回的函数
如何解绑一些副作用
useEffect 可以传入两个函数
useState(()=>{
const subScription = props.source.subScribe();
return ()=>{ } // 返回一个函数, 可以执行解绑副作用
},[props.source]) // 第二个参数帮助优化渲染,比如我们传入了一个state值, 那就是只有这个值发生变化的时候才会执行这个函数
如果想执行只运行一次的Effect(只在组件卸载和挂载时执行),可以只传入一个空数组作为第二个参数,就是告诉你你的effect不依赖props和state的任何值,不会重复执行
四、额外的一些Hooks : useContext、useReducer、useRef
1、useContext
在context 这个api 出来之前,数据流向只能自上而下,从父组件一层一层的往下传递, 比如
一个数据要传到他使用的组件, 但是中间要经历三个组件, 我们就得在这三个组件中处理该数据的传递逻辑,但是对于这三个组件这些逻辑是毫无意义的, 这个时候我们就可以用Context; 而在Hooks 里面就提供了useContext 这样的Api;
在我们之前的项目中, 我们用到的Redux 其实也是这样的原理,我们会在项目的最顶层自定义一个父组件Provider,把全局会用到的数据和状态都放在这个组件里面进行管理,当项目中的所有组件都是Provider 的子组件时,那相互的数据交互肯定就不是问题了,那接下来我们通过一个例子来看下useContext如何使用
我们要创建一个context文件, 将创建的Context对象抛出, 因为最上层的组件, 和他包含的子组件都要用到这个Context对象;
在Context对象中, 提供了一个自带的Provider组件, 该组件接收一个value 作为参数, 我们将自定义的对象和数据通过该参数传入context 对象
在子组件中, 我们可以使用useContext 订阅这个对象。这样Context对象中的数据变化, 其他组件也就能接收到了, 当然我们也可以同时创建多个context 对象, 在使用时, 使用哪个useState订阅哪个就可以。
以上是 十分钟学会 React Hooks 的全部内容, 来源链接: utcz.com/z/383098.html