react-hook 详解及使用-3
此篇文章主要介绍 react-hook 详解及使用-3
注意:
React 16.8.0 是第一个支持 Hook 的版本。升级时,请注意更新所有的 package,包括 React DOM。 React Native 从 0.59 版本开始支持 Hook。
Hook 在 class 内部是不起作用的。但你可以使用它们来取代 class 。
1.react-hook 之 什么是 HOOK?
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
Hook 是一个特殊的函数,它可以让你“钩入” React 的特性。
2.react-hook 之 为什么要使用 HOOKS
- Hook 使你在无需修改组件结构的情况下复用状态逻辑
- Hook 将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据)
- Hook 使你在非 class 的情况下可以使用更多的 React 特性
3.Hook 使用规则
Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
- 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
- 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中,我们稍后会学习到。)
4.Hook 常见钩子
useContext
const value = useContext(MyContext);
MyContext
对象TestContext.Provider包裹子组件
数据放在<TestContext.Provider value={value}>的value中
子组件中通过useContext(
MyContext
)获取值- 正确:
useContext(MyContext)
- 错误:
useContext(MyContext.Consumer)
- 错误:
useContext(MyContext.Provider)
import React, { useContext, useState } from 'react';
const TestContext = React.createContext();
const Parent = () => {
const [value, setValue] = useState(0);
return (
<div>
{(() => console.log("Parent-render"))()}
<button onClick={() => setValue(value + 1)}>value + 1</button>
<TestContext.Provider value={value}>
<Child1 />
<Child2 />
</TestContext.Provider>
</div>
);
}
const Child1 = () => {
const value = useContext(TestContext);
return (
<div>
{(() => console.log('Child1-render'))()}
<h3>Child1-value: {value}</h3>
</div>
);
}
const Child2 = () => {
return (
<div>
{(() => console.log('Child2-render'))()}
<h3>Child2</h3>
</div>
);
}
export default Parent
5.额外的 Hook
(1) useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
(2) useCallback
语法:
// useCallback(回调函数,[依赖值])
const handleClick = useCallback(()=> {
// 做一些事
}, [value]);
(3)useMemo
语法:
// useMemo(回调函数,[依赖值])
useMemo(() => {
// 做一些事情
},[value]);
例子:
import React, { useState, useMemo } from 'react'
const Test = ()=> {
const [value, setValue] = useState(0);
const [count, setCount] = useState(1);
const getDoubleCount = useMemo(() => {
console.log('getDoubleCount进行计算了');
return count * 2;
},[count]);
return (
<div>
<h2>value: {value}</h2>
<h2>doubleCount: {getDoubleCount}</h2>
<button onClick={() => setValue(value + 1)}>value+1</button>
</div>
)
}
export default Test
getDoubleCount只有依赖的count发生变化时才会重新计算渲染。
(4)useRef
用法同 React.createRef(),但是createRef每次渲染都会返回一个新的引用
简单来说,useRef就像一个储物箱,你可以随意存放任何东西,useRef每次都会返回相同的引用