【开始学习React Hook(2)】Hook之useEffect
是什么?
使用useEffect,表示告诉react, 每次render (这里没写错,是每次render,包括第一次render和之后的每次update)之后需要做一些事情,什么事情呢?就是你写在useEffect里的代码。
结构:
useEffect(()=>{
// part A
return part B;
和react 类相比较,也就是放在componentDidMount,componentDidUpdate里的代码,以及调用完setState之后需要做的事( 也就是采用此方式:this.setState({}, ()=>{ // 更新完此state值之后需要做的事 }))统统移到useEffect里。
怎么用?
1. 单个useEffect使用
不管是react初次画好组件,还是之后的更新完组件,都会去执行useEffect的part A。如果你还返回了part B,那么react在卸载组件之前,以及每次执行part A去更新组件前,都会执行part B。当然你也可以不返回任何东西。
实际上,我们可以把useEffect看成componentDidMount, componentDidUpdate, componentWillUnMount的合体。Part A是写在componentDidMount和componentDidUpdate的代码,part B是写在componentWillUnMount的代码。
有人可能会说,我只想在componentDidMount和componentWillUnMount时执行代码。那么给useEffect加第二个参数,一个空数组。
useEffect(()=>{
// part A
return part B;
}, []);
第二个参数表示useEffect里面的part A和part B不依赖任何props, state, 因此不需要再次render,也就是这个useEffect只在componentDidMount和componentWillUnMount时执行代码。而part A, part B里涉及到的props和state始终是初始值,不会被更新。
如果第二个参数传[ list ],表示useEffect会在list发生改变时执行。也就是在
componentDidMount,componentDidUpdate( 检测到list更新之后)和componentWillUnMount时执行。
2. 多个useEffect使用。
也许我们会有这种情况,两个不同的业务逻辑都需要使用useEffect,那么我们可以分开写,每个业务逻辑放在一个useEffect里。react处理多个useEffect时,会按照代码里的顺序从上至下执行。
实践例子
例如,有一个需要从后端获取数据的列表,列表上方有一个可用于搜索列表项的表单。那么,在componentDidMount里我们需要从后端获取数据设置列表的数据源,在componentDidUpate 里需要根据用户填写的搜索值再次调用后端接口更新列表的数据源。写hook组件时,需要有一个useEffect来处理列表的数据源,而该数据源依赖用户输入的搜索值。
jsx文件如下:
import React , { useState, useEffect } from 'react';
import {Form,Input, Table} from 'antd';
const source = [
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
key: '2',
name: 'John',
age: 42,
address: '10 East Street',
const columns = [
title: 'Name',
dataIndex: 'name',
key: 'name',
title: 'Age',
dataIndex: 'age',
key: 'age',
title: 'Address',
dataIndex: 'address',
key: 'address',
function UseEffectExample() {
const [ dataSource, setDataSource] = useState([]);
const [ search, setSearch ] = useState({ name: '', address: ''});
const searchChange = (e, key) => {
const newValue = e.target && e.target.value;
search[key] = newValue;
setSearch(Object.assign({}, search));
const fetchData = (search) => {
// 调用后端拿数据,这里在前端简单mork数据
let result = source;
if(search.name.trim() !== ''){
result = result.filter((item)=>{
return item.name.indexOf(search.name) > -1;
if(search.address.trim() !== ''){
result = result.filter((item)=>{
return item.address.indexOf(search.address) > -1;
return result;
useEffect(()=>{
const newData = fetchData(search);
setDataSource(newData);
}, [search]);
return (
<div className="list-page">
<Form layout="inline">
<Form.Item label="Name">
<Input value={search.name} onChange={(e)=> searchChange(e, 'name')}/>
</Form.Item>
<Form.Item label="Address">
<Input value={search.address} onChange={(e)=> searchChange(e, 'address')}/>
</Form.Item>
</Form>
<Table dataSource={dataSource} columns={columns} />