前言
虽然react一般都是class类的方式编写,但有时为了简单,就使用函数编写,但在以前这是无副作用的函数,所以很多事都无法去做,比如后期为了维护而不得不在函数里使用state等时,这就不会符合无副作用的函数了,所以react会报错,而这是使用hooks就可以拯救啦,当然也有喜欢使用函数式编写的人来说也是福音,因为hooks基本上支持所有react生命周期,state,redux等等,与编写class方式差不多等效了。
State
引入react里的useState。
useState的参数就像state初始化值。
useState返回的值一个数组,数组中第一个参数是以前的state,第二个参数是setState,由于是参数,所以可以自己命名,不用想以前就state,setState这样。
例子如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import React, { Component, useState, useEffect } from 'react';
import { InputItem, List } from 'antd-mobile';
export const getText = function(props){
const [test, setTest] = useState('');
function onChange(val){
setTest(val);
}
return (
<div>
<List>
<InputItem value={test} onChange={onChange}>hooks测试</InputItem>
</List>
<List>
<div>{test}</div>
</List>
</div>
);
}
Effect
引入react里的Effect。
useEffect增加了从功能组件执行副作用的功能,其实这个钩子就是让函数支持react生命周期。
它的目的是作为componentDidMount,componentDidUpdate以及componentWillUnmount,只是都在这个useEffect钩子实现。
useEffect的第二参数为空数组[],效果如componentDidMount:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import React, { Component, useState, useEffect } from 'react';
import { InputItem, List } from 'antd-mobile';
export const getText = function(props){
// 调用父级组件函数更新state
useEffect(()=>{
props.setVal(Math.floor(Math.random()*100));
},[]);
return (
<div>
<List>
<div>{props.value}</div>
</List>
</div>
);
}useEffect的第二参数不传,效果如componentDidUpdate,但初始加载也会触发:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import React, { Component, useState, useEffect } from 'react';
import { InputItem, List } from 'antd-mobile';
export const getText = function(props){
// 调用父级组件函数更新state
useEffect(()=>{
props.setVal(Math.floor(Math.random()*100));
});
return (
<div>
<List>
<div>{props.value}</div>
</List>
</div>
);
}useEffect里函数的返回值,效果如componentWillUnmount,在组件卸载调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import React, { Component, useState, useEffect } from 'react';
import { InputItem, List } from 'antd-mobile';
export const getText = function(props){
const timer = setInterval(()=>{
console.log(+new Date());
});
// 调用父级组件函数更新state
useEffect(()=>{
props.setVal(Math.floor(Math.random()*100));
return ()=>{
clearInterVal(timer);
}
});
return (
<div>
<List>
<div>{props.value}</div>
</List>
</div>
);
}useEffect的第二参数数组有对应的state或props值,只要当前值更新了才触发:
1 | import React, { Component, useState, useEffect } from 'react'; |
自定义钩子
就是抽取相同逻辑的部分封装成一个新的钩子,而钩子使用hooks的钩子封装实现,然后返回一个目标内容,如值。
自定义钩子:1
2
3
4
5
6
7
8
9
10import React, { Component, useState, useEffect } from 'react';
export const getHook = function(vId,props){
const [ssId, setSsId] = useState('');
useEffect(()=>{
props.setVal(Math.floor(Math.random()*100));
setSsId(vId);
},[props.value]);
return ssId;
}
使用自定义钩子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import React, { Component, useState, useEffect } from 'react';
import { InputItem, List } from 'antd-mobile';
improt {getHook} from './hooks';
export const getText = function(props){
const nVal = getHook("xx",props);
return (
<div>
<List>
<div>{props.value}</div>
</List>
</div>
);
}
使用规则
- 只能在顶层调用Hooks。不要在循环,条件或嵌套函数中调用Hook。
- 只能在functional component中使用,所以如果在class使用一定要是组件的形式,而不是函数调用的方式,不是会当成一个在class里使用hooks。
参考
react官网有很详细的资料,而且以上的只是当用的,Hooks还提供了别的钩子。
react官方Hooks