一、什么是Hooks
Hooks 是 React 16.8 的新增特性。在不编写 class 的情况下使用 state 以及其他的 React 特性。Hooks 是一种在函数式组件中使用有状态函数的方法。
二、类组件
componentDidMount
、componentDidUpdate
和 componentWillUnmount
这三个函数的组合。
三、常用的Hook Api
- useState
- useEffect
- useContext
- useCallback
- useMemo
- useRef
- useImperativeHandle
1、useState使用
import React, { useState } from 'react';
2 import {
3 SafeAreaView,
4 Text,
5 TouchableOpacity
6 } from 'react-native';
7 import Constants from './expand/dao/Constants';
8 import { post } from './expand/dao/HiNet';
9 export default (props: any) => {
10 const [msg, setMsg] = useState('');
11 const doFetch = () => {
12 const formData = new FormData();
13 formData.append("requestPrams", 'RN');
14 post(Constants.test.api)(formData)().then(result => {
15 setMsg(JSON.stringify(result));
16 }).catch(e => {
17 console.log(e);
18 setMsg(JSON.stringify(e));
19 })
20 }
21 return (
22 <SafeAreaView>
23 <TouchableOpacity onPress={doFetch}>
24 <Text>加载</Text>
25 </TouchableOpacity>
26 <Text>{msg}</Text>
27 </SafeAreaView>
28 );
29 };
从上述代码中我们不难看出,在React Native中使用State Hook
的主要步骤:
- 导入
useState
:import React, { useState } from 'react';
- 通过
useState
定义state:const [msg, setMsg] = useState('');
- msg是定义的state中一个变量,setMsg是用来修改msg变量的关联函数,它的格式是
set+变量名首字母大写
- msg是定义的state中一个变量,setMsg是用来修改msg变量的关联函数,它的格式是
- 修改状态:通过前面定义的关联函数
setMsg
修改即可setMsg(JSON.stringify(result));
State Hook
的作用范围:因为Hooks只能应用与函数式组件,所以通过它声明的state的作用范围是函数内。
Hook 简介 – React2、useEffect使用
import React, { useState, useEffect } from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity
} from 'react-native';
import Constants from './expand/dao/Constants';
import { post } from './expand/dao/HiNet';
export default (props: { navigation: any }) => {
const [msg, setMsg] = useState('');
useEffect(() => {
//对应componentDidUpdate
function handleStatusChange(status: any) {
console.log(status);
}
const timer = setTimeout(() => {
doFetch();
}, 2000);
// 对应componentWillUnmount
return function cleanup() {
timer && clearTimeout(timer);
};
});
const doFetch = () => {
const formData = new FormData();
formData.append("requestPrams", 'RN');
post(Constants.test.api)(formData)().then(result => {
setMsg(JSON.stringify(result));
}).catch(e => {
console.log(e);
setMsg(JSON.stringify(e));
})
}
return (
<SafeAreaView>
<TouchableOpacity onPress={doFetch}>
<Text>加载</Text>
</TouchableOpacity>
<Text>{msg}</Text>
</SafeAreaView>
);
};
- 导入
useEffect
:import React, { useState,useEffect } from 'react';
- 使用
useEffect
来实现不同生命周期函数的hooks:- 直接写在
useEffect(() => {}
一层的会在组件装载时调用,对应componentDidMount handleStatusChange
对应componentDidUpdate
cleanup
对应componentWillUnmount
在组件卸载时调
- 直接写在
3、useContext使用
const value = useContext(MyContext);
接收一个 context 对象(React.createContext
的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider>
的 value
prop 决定。
当组件上层最近的 <MyContext.Provider>
更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext
provider 的 context value
值。即使祖先使用 React.memo 或 shouldComponentUpdate,也会在组件本身使用 useContext
时重新渲染。
4、useCallback使用
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
把内联回调函数及依赖项数组作为参数传入 useCallback
,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate
)的子组件时,它将非常有用。
useCallback(fn, deps)
相当于 useMemo(() => fn, deps)
。
5、useMemo使用
把“创建”函数和依赖项数组作为参数传入 useMemo
,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
6、useRef使用
useRef
返回一个可变的 ref 对象,其 .current
属性被初始化为传入的参数(initialValue
)。返回的 ref 对象在组件的整个生命周期内持续存在。
7、useImperativeHandle使用
useImperativeHandle
可以让你在使用 ref
时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle
应当与 forwardRef 一起使用:
8、Hook useMemo useCallback 的区别
useMemo
用于优化计算开销大的操作。它会记忆一个值,只有当依赖项改变时,才会重新计算这个值。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
在上面的例子中,computeExpensiveValue
是一个计算开销很大的函数,它依赖于变量 a
和 b
。只有当 a
或 b
改变时,computeExpensiveValue
才会重新计算。
使用场景:
- 计算开销大的值。
- 需要重用计算结果以避免不必要的计算。
useCallback
用于优化传递给子组件的回调函数。
Hook 简介 – React
React Native Hooks开发指南