Hook是React 16.8 的新增特性伟桅。
在hook出現(xiàn)之前叽掘,使用react有一些痛點(diǎn),簡單整理如下幾點(diǎn):
由于業(yè)務(wù)變動更扁,函數(shù)組件必須不得不改為類組件
組件邏輯復(fù)雜時難以開發(fā)和維護(hù)
一個邏輯難以跨組件使
目的:加強(qiáng)函數(shù)組件浓镜,完全不使用"類",就能寫出一個全功能的組件膛薛。
使用限制:
1、只能在函數(shù)最外層調(diào)用 Hook遵绰。不要在循環(huán)、條件判斷或者子函數(shù)中調(diào)用乌企。
2成玫、只能在 React 的函數(shù)組件中調(diào)用 Hook。不要在其他 JavaScript 函數(shù)中調(diào)用哭当。(還有一個地方可以調(diào)用 Hook —— 就是自定義的 Hook 中。)
import React, { PureComponent, useState } from 'react';
export default class Counter extends PureComponent {
render () {
const count = 1;
return (
<h1>來{count}碗大碗寬面</h1>
);
}
}
import React from 'react';
export default function Counter() {
const count = 1;
return (
<h1>來{count}碗大碗寬面</h1>
);
}
這種寫法有重大限制陋葡,必須是純函數(shù)彻采,不能包含狀態(tài)肛响,也不支持生命周期方法,因此無法取代類
Hook
useState
useEffect
useCallback
useContext
useReducer
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue
ueState
1特笋、返回一對值(當(dāng)前值和一個讓你更新它的函數(shù))
2猎物、通過在函數(shù)組件里來調(diào)用它給組件添加一些內(nèi)部state,react會在重新渲染時保留這個state
類組件
import React, { PureComponent, useState } from 'react';
import { Button } from 'antd-mobile';
export default class Counter extends PureComponent {
constructor(props) {
super(props);
this.state = { count: 1 };
}
render () {
const { count } = this.state;
return (
<div>
<h1>來{count}碗大碗寬面</h1>
<Button onClick={() => this.setState({ count: count + 1 })}>加一碗</Button>
</div>
);
}
}
函數(shù)組件
import React, { useState } from 'react';
import { Button } from 'antd-mobile';
export default function Counter() {
const [count, setCount] = useState(1);
return (
<div>
<h1>來{count}碗大碗寬面</h1>
<Button onClick={() => setCount(count + 1)}>加一碗</Button>
</div>
);
}
狀態(tài):既放在state中的變量溜宽,比如上面例子中的count
更改狀態(tài)的函數(shù):類似class組件中的this.setState质帅,上面例子的setCount留攒,通過setCount(count+1)重新賦值更改狀態(tài)
初始狀態(tài):在初始化hook的時候通過useState(1)賦值,其中1就是初始狀態(tài)
useEffect
class組件
import React from 'react';
import { Button, Toast } from 'antd-mobile';
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 1,
big: true,
type: '寬面'
};
}
componentDidMount() {
if (this.state.type !== '寬面') {
Toast.info('今天只能吃寬面');
}
}
componentDidUpdate() {
if (this.state.type !== '寬面') {
Toast.info('今天只能吃寬面');
}
}
render() {
const { count, big, type } = this.state;
const size = big ? '大' : '小';
return (
<div>
<div>來{count}碗{size(big)}碗{type}</div>
<Button onClick={() => this.setState({ count: count + 1 })} style={{ 'height': '40px' }}>加一碗</Button>
<Button onClick={() => this.setState({ big: !big })} style={{ 'height': '40px' }}>{size}碗</Button>
<Button onClick={() => this.setState({ type: '細(xì)面' })} style={{ 'height': '40px' }}>不想吃寬面</Button>
</div>
);
}
使用useEffect
import React, { useEffect, useState } from 'react';
import { Button, Toast } from 'antd-mobile';
export default function Counter() {
const [count, setCount] = useState(1);
const [big, setSize] = useState(true);
const [type, setType] = useState('寬面');
const size = big ? '大' : '小';
useEffect(() => {
if (type !== '寬面') {
Toast.info('今天只能吃寬面');
}
});
return (
<div>
<div>老板,來{count}碗{size(big)}碗{type}</div>
<Button onClick={() => setCount(count + 1)}>加一碗</Button>
<Button onClick={() => setSize(!big)}>{size}碗</Button>
<Button onClick={() => setType('細(xì)面')}>不想吃寬面</Button>
</div>
);
useEffect參數(shù)
1洛退、如果什么都不傳,會在每次渲染后都執(zhí)行兵怯,也就是說在第一次渲染之后和每次更新之后都會執(zhí)行。
2驼仪、如果傳一個空數(shù)組袜漩,那么就只會運(yùn)行一次effect,并且effect內(nèi)部的 props 和 state 會一直擁有其初始值宙攻。
3座掘、如果傳的是一個包含屬性值的數(shù)組,那么只有當(dāng)數(shù)組里的值發(fā)生變化的時候才會觸發(fā)useEffect回調(diào)雹顺。
// 相當(dāng)于 componentDidMount 和 componentDidUpdate
useEffect(() => {
console.log(`You clicked ${count} times`);
});
// 由于第二個參數(shù)傳的是空數(shù)組,所以這里相當(dāng)于componentDidMount
useEffect(() => {
...
// 相當(dāng)于componentWillUnmount
return () => {};
}, []);
// 相當(dāng)于 componentDidMount 和 componentDidUpdate
useEffect(() => {
console.log(`You clicked ${count} times`);
}, [count]);
對比于以前react class的寫法贩挣,可以把useEffect看做 componentDidMount没酣,componentDidUpdate 和 componentWillUnmount 這三個函數(shù)的組合。
自定義Hook
所有的鉤子都是為函數(shù)引入外部功能绒净,所以 React 約定偿衰,鉤子一律使用use前綴命名,便于識別下翎。你要使用 xxx 功能,鉤子就命名為 usexxx胆萧。
參考資料
React Hooks 入門教程:http://www.ruanyifeng.com/blog/2019/09/react-hooks.html
react 16.7 hook概述:http://www.reibang.com/p/e61faf452565
hook詳解:https://blog.csdn.net/tonydz0523/article/details/106479182
React Hooks 拓展鉤子和自定義Hook的使用:http://www.reibang.com/p/0510d6f83dce
理解React Hooks:http://www.reibang.com/p/d6244228a427