react hooks useEffect副作用钩子使用

    react框架开发作为入门,我们首先学到的是自定义组件,然后编写相关处理逻辑,绑定事件等等。一般自定义组件,我们是通过编写一个class继承React.Component,然后编写最主要的render等方法,另外,我们还可能需要考虑到组件的生命周期componentDidMount,componentDidUpdate这些方法,当我们的组件很简单的时候,这么做就显得有些笨重,不利于维护,比如:

class Hello extends React.Component{
	render(){
		return <div>hello,world</div>
	}
}
export default Hello

    这是一个最简单的react组件,但是代码为了实现组件的功能,继承React.Component,然后在render()方法中返回元素。其实这个组件不涉及到状态state的改变,因此可以通过function函数的形式来实现,会更加的简单。

export const Hello = () => <div>hello,world</div>

    这是精简过后的代码,看着很舒服,没有什么累赘。这样的组件也叫无状态组件(stateless component)。现在react已经推荐使用无状态组件来实现react的组件了,那么问题也来了,既然通过函数function取代class来定义组件,那么状态怎么维护呢?生命周期怎么维护?

    这就是react hooks解决的问题:通过定义useState,useReducer,useEffect等钩子来解决组件状态,组件生命周期问题。useEffect默认可以当做class中的componentDidMount生命周期:只在组件挂载的时候运行一次。useEffect的语法如下:

    useEffect(()=>{
        //todo
    },[])

     默认useEffect可以不用带第二个参数也就是[],可以简写成如下:

    useEffect(()=>{
        //todo
    })

     我们来看看如下示例,可以看到,useEffect方法调用会执行一次。

import React,{useState,useEffect} from 'react'

const App = ()=>{

	const [allTypes,setAllTypes] = useState([])

	useEffect(()=>{
		//setAllTypes([{id:1,name:'aaa'},{id:2,name:'bbb'}])
		console.log("componentDidMount...")
	})

	return (
			<div>
				<h2>hello,react.</h2>
				<ul>
					{allTypes.map(t=><li key={t.id}>{t.name}</li>)}
				</ul>
			</div>
		)
	
}

export default App

     

    这个示例中,通过useEffect实现了类似componentDidMount的功能,但是会有一个很大的风险,当我们打开注释:setAllTypes([{id:1,name:'aaa'},{id:2,name:'bbb'}]),页面会出现无限循环的执行useEffect中的函数。

    

扫描二维码关注公众号,回复: 10819407 查看本文章

    其实默认,如果去掉useEffect的默认参数[],会导致在页面发生改变的时候也会执行,好比class方式中的componentDidUpdate生命周期函数,解决这个问题的办法就是给useEffect添加这个默认参数[]。

     

    页面也不会报错,正常运行。

     

    其实useEffect这第二个参数[],是监听的对象数组,当监听的对象数组中没有任何值也就是不监听依赖对象,这时候,无论页面如何update,都不会再发生无线循环渲染的问题。 所以只会在类似componentDidMount生命周期下运行一次,之后componentDidUpdate的时候,因为监听对象为空,所以认为没有update发生,所以不会执行。

发布了529 篇原创文章 · 获赞 287 · 访问量 147万+

猜你喜欢

转载自blog.csdn.net/feinifi/article/details/103931907