• React useEffect


    今早来又莫名其妙的遇到了 bug,排查了一下是 useEffect 导致的。今天就再来详细的学习一下 react useEffect。

    为什么要?

    我们知道,react 的函数组件里面没有生命周期的,也没有 state,没有 state 可以用 useState 来替代,那么生命周期呢?

    useEffect 是 react v16.8 新引入的特性。我们可以把 useEffect hook 看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三个函数的组合。

    详解

    原来我们是这么写 class component

    class LifeCycle extends React.Component {
    	constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
      componentDidMount() {
        document.title = `you clicked me ${this.state.count} times`;
      }
      componentDidUpdate() {
        document.title = `you clicked me ${this.state.count} times`
      }
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={()=> this.setState({count: this.state.count + 1})}>
            	Click me
            </button>
          </div>
        )
      }
    }
    

    现在我们使用 hook 来写 function component

    import React, { useState, useEffect } from 'react';
    function Example() {
    	const [count, setCount] = useState(0);
    	useEffect(() => {
    		document.title = `you clicked ${count} times`;
    	})
    	return (
    		<div>
    			<p>You clicked {count} times</p>
    			<button onClick={() => setCount(count + 1)}
    				Click me
    			</button>
    		</div>
    	)
    }
    

    上面的这段代码,每次 count 变更以后,effect都会重新执行。

    我们日常开发中,获取数据、订阅以及手工更改 React 组件中的 DOM(我之前就更改过)都属于副作用。有些副作用可能需要清除,所以需要返回一个函数,比如设置定时器、清除定时器。

    class Example extends Component {
    	constructor(props) {
    		super(props);
    		this.state = {
    			count: 0;
    		}
    	}
    	componentDidMount() {
    		this.id = setInterval(() => {
    			this.setState({count: this.state.count + 1})
    		}, 1000)
    	}
    	componentWillUnmount() {
    		clearInterval(this.id)
    	}
    	render() {
    		return <h1>{this.state.count}</h1>;
    	}
    }
    

    使用 Hook 的示例

    function Example() {
    	const [count, setCount] = useState(0);
    	useEffect(() => {
    		const id = setInterval(() => {
    			setCount(c => c + 1);
    		}, 1000);
    		return () => clearInterval(id);
    	}, []);
    	return <h1>{count}</h1>
    }
    

    我们可以让 React 跳过对 effect 的调用,让 effect 的执行依赖于某个参数(传利数组作为 useEffect 的第二个可选参数就可以了)。倘若仅仅只想执行一次,那么就传递一个空的数组作为第二个参数,这个时候 useEffect hook 不依赖于 props 或者任何值,所以永远都不重复执行。

    在过去的性能优化里,在某些情况下,每次渲染后都执行清理或者执行 effect 都可能会导致性能的问题。在 class 组件中,我们通过在 componentDidUpdate 添加 prevProps或者 prevState 来解决。

    componentDidUpdate(prevProps, prevState) {
    	if(prevState.count !== this.state.count) {
    		document.title = `You clicked ${this.state.count} times`
    	}
    }
    

    这个是非常常见的需求。而如今,倘若我们使用 function component,代码会非常的简洁。

    useEffect(() => {
    	document.title = `You clicked ${count} times`;
    }, [count])
    

    总结

    Hook 是对函数式组件的一次增强,v16.8 出现以后才出来的 hook 特性。在这之前,我看有的代码里面,通过一个<InitialCallBack>来放到函数时组件的最前面,通过在<InitialCallBack>的 componentDidMount 来获取后端接口数据。

    就是变相的往 Hook 里面引入生命周期。

    然而 v16.8 出来了,这个问题完全解决了。

    Hook的语法更简洁易懂,消除了 class 的声明周期方法导致的重复逻辑代码。

    同时,在某种程度上解决了高阶组件难以理解和使用的问题。

    然而 Hook 并没有让函数时组件做到 class 组件做不到的事情,只是让很多组件变得写的更简单。class 组件不会消失,hook 化的函数时组件将是趋势。

  • 相关阅读:
    视图类、二次封装、视图家族、GenericAPIView视图基类、mixins视图6大工具类、generic中的工具视图、路由组件
    单改、整体/局部修改、群改接口
    多表、序列化反序列化、群增单删群删接口
    解析模块
    drf框架
    vue-04
    vue-03
    VUE-02
    vue
    ❥《python入门到入土》全教程❥
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13272166.html
Copyright © 2020-2023  润新知