react的几种常见的钩子
01.useEffect()
副作用钩子
useEffect用来引入具有副作用的操作,最常见的就是向服务器请求数据
useEffect(() => {
// Async Action
}, [dependencies])
useEffect接受两个参数。第一个参数是一个函数,异步操作的代码放在里面。第二个参数是一个数组,用于给出Effect的依赖项,只要这个数组里的内容发生变化,useEffect就会执行。第二个参数可以省略,每次组件渲染时,就会执行useEffect。就是说工作流程为第二个参数里面某个内容发生变动之后,第一个参数的函数就会执行,这个被依赖项控制的函数可以执行发送请求调数据,或者修改网页标题之类的,就是说这类事情就是项目的副作用。
与数据计算无关的操作,称为“副效应” (side effect)
useStatr():保存状态
useContext():保存上下文
useRef():保存引用
这些都是引入某种特定的副效应,而useEffect()是通用的副效应钩子
当有多个副效应要使用时,应该直接调用多个useEffect(),而不应该合并写咋在一起
02.useCallback()
是用来优化性能的
useCallback返回一个函数,只有在依赖项发生变化的时候才会更新(返回一个新的函数)
有一个场景,一个a组件(父)包裹一个b组件(子),a组件又一个函数叫aC,aC被当做b组件的props被传进b组价。然后,关键点来了,当aC这个函数在a组件里面发生更改之后,b组件的props也自然就会发生变化了,那么b组件就会自动更新,但其实这种更新是没有必要的(因为有的时候aC的更改并不会对内容产生变化),所以我们会在a组件里面把aC这个函数用useCallback来保存。
但只是这样还不行,还需要和React.memo合用
React.memo是一个高阶函数
React.memo会检查props的变更,如果函数组件被React.memo包裹,且其内部拥有useState,useRducer或useContext的Hook,当context发生变化时,它仍会重新渲染,而context没有变化的话,就不会重新渲染
以下例子在按下按钮后只会重新渲染一次(context更改那次)
import React, { useState } from 'react'
const Test: React.FC<IObjectProps> = () => {
let [context, setContext] = useState(0)
const addHandle = (): void => {
// 这里固定设置count的值为1
setContext(1)
}
return (
<div style={
{ padding: '10px' }}>
{console.log('dom 渲染')}
<p>{count}</p>
<button onClick={addHandle}>Add</button>
</div>
)
}
// 使用React.memo包裹组件
export default React.memo(Test)
03.useMemo()
也是有两个参数,第一个是一个函数,用于执行要完成的任务,第二个是依赖项。基本结构与useCallback差不多
与useEffect不同的是,useMemo是执行于组件渲染中的,而useEffect因为是对副效应进行操作,所以是执行于组件渲染之后的
与useCallback()的区别
1.useMemo缓存的结果是回调函数中return回来的值,主要用于缓存计算结果的值,应用场景如需要去计算的状态
2.useCallback缓存的结果是函数,主要用于缓存函数,应用场景如需要缓存的函数,因为函数式组件每次任何一个state发生变化,会触发整个组件更新,一些函数是没有必要更新的,此时就应该缓存起来,提高性能,减少对资源的浪费;另外还需注意的是,useCallback应该和React.memo配套使用,一个不能缺。
04.useParams
用来获取组件的地址,返回当前route的match.params
let{path} = useParams<any>();
05.useLocation
监听url的location对象,可以将其视为类似于url更改时useState会返回的新值的location返回的内容大概是这样
{
key: 'ac3df4', // not with HashHistory!
pathname: '/somewhere',
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
06.useHisatory
返回一个对象,这个对象可以使用两种方法:push和replace实现编程式导航,push增加新页,可以使用后退按钮返回到上一个页面,replace不能返回
import { useHistory } from "react-router-dom";
import QuoteForm from "./../components/quotes/QuoteForm";
const NewQuote = () => {
const history = useHistory();
const addQuoteHandler = (quoteData) => {
console.log(quoteData);
history.push("/quotes");
};
return <QuoteForm onAddQuote={addQuoteHandler} />;
};
export default NewQuote;
以上例子使用的了push方法