【React Hooks】useEffect 用法

文章目录

    • 什么是副作用 effect
    • useEffect 基本用法
    • useEffect 与生命周期

什么是副作用 effect

本来吃这个药,我只是想治个感冒而已,结果感冒虽然治好了,但是却过敏了。过敏便是副作用。

本来我只是想渲染DOM而已,可是当DOM渲染完成之后,我还要执行一段别的逻辑。这一段别的逻辑就是副作用。

在React中,如果利用得好,副作用可以帮助我们达到更多目的,应对更为复杂的场景。

  • 常见的副作用操作:
1. 发送ajax请求数据获取
2. 设置订阅
3. 手动更改真实DOM
4. 启动定时器/延时器

当然,如果hold不住,也会变成灾难,例如:

import React, { useState, useEffect } from 'react';
import './style.scss';
// 每个React组件初始化时,DOM都会渲染一次
export default function AnimateDemo() {
  const [counter, setCounter] = useState(0);

  // DOM渲染完成之后副作用执行
  useEffect(() => {
    setTimeout(() => {
      // 副作用:完成后的一秒钟,counter加1
      setCounter(counter + 1);
    }, 1000);
  });

  return (
    <div className="container">
      <div className="el">{counter}</div>
    </div>
  )
}
  • 猜猜最后的结果?
  • 结果就是:counter不停的在累加,陷入死循环
  • 分析下原因:
1. DOM渲染完成,副作用逻辑执行
2. 副作用逻辑执行过程中,修改了counter,而counter是一个state值
3. state改变,会导致组件重新渲染
4. 组件重新渲染,副作用再次逻辑执行
  • 要避免这种灾难怎么办?就要利用useEffect的第二个参数来帮助我们。
/*
	当第二个参数传入空数组,即没有传入比较变化的变量,
	则比较结果永远都保持不变,那么副作用逻辑就只能执行一次。
*/ 
useEffect(() => {
  setTimeout(() => {
    setCounter(counter + 1);
  }, 300);
}, []);

useEffect 基本用法

  • 语法和说明:
useEffect(()=>{
	// 在此可以执行任何带副作用操作
	return()=>{// 在组件卸载前执行
		// 在此做一些收尾工作,比如清除副作用
	}
},[stateValue])	// 如果指定的是[],回调函数只会在第一次render()后执行
  • useEffect 可以在组件渲染后实现各种不同的副作用。
  • 有些副作用可能需要清除,所以需要返回一个函数:
useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  • 其他的 effect 可能不必清除,所以不需要返回。
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

useEffect 与生命周期

  • 类组件
//useState 使用状态值,第一个 hook
//1.引入useState  钩子
import React, { Component } from 'react';
class App extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 10 }
  }
  //挂载后
  componentDidMount() {
    console.log("componentDidMount运行了");

  }
  //更新后
  componentDidUpdate() {
    console.log("componentDidUpdate 运行了");

  }
  //销毁前
  componentWillUnmount() {
    console.log("componentWillUnmount 运行了");

  }
  changeCount = () => {
    this.setState({ count: this.state.count + 1 })
  }
  render() {
    return (<div>类组件,钩子

      {this.state.count}
      <button onClick={this.changeCount}>+</button>
    </div>);
  }
}

export default App;
  • 使用useEffect Hook
//1.引入useState  钩子
import React, { useState, useEffect } from 'react';
function App() {

  const [count, setCount] = useState(10);
  const [age, setAge] = useState(18);
  const changeCount = () => {
    setCount(count + 1)
  }
  const changeAge = () => {
    setAge(20);
  }
  //1.useEffect 只有一个参数
  /*
  useEffect  只有一个参数的时候,相当于  componentDidMount  + componentDidUpdate
  */
  // useEffect(() => {
  //   console.log("useEffect 运行了");
  // })

  //2. useEffect  使用两个参数
  /*
  参数1:函数
  参数2:数组  ,依赖哪个数据发生变化时触发
  */
  //第二个参数是空数组  ,useEffect  相当于挂载后componentDidMount
  // useEffect(() => {
  //   console.log("useEffect 运行了");
  // }, [])

  //3.第二个参数不是空数组 ,定义了触发这个钩子函数的依赖项,
  //组件挂载时触发一次
  //依赖项发生变化时,该钩子函数也会被调用
  //
  // useEffect(() => {
  //   console.log("useEffect 运行了 ,count: " + count);
  // }, [count])

  //4.相当于卸载前的钩子函数
  //当 useEffect 的第二个参数为空数组时,在函数中的return 的函数里执行的操作相当于卸载componentWillUnmount
  useEffect(() => {
    console.log("挂载运行了");
    //卸载:清除定时器、清除绑定事件,结束未完成的axios数据获取
    return () => {
      console.log("卸载钩子函数运行了 ");
    }
  }, [])


  return (
    <div>类组件,钩子

      {count}
      <button onClick={changeCount}>+</button>

      年龄:{age}
      <button onClick={changeAge}>改变年龄</button>

    </div>
  )

}
export default App;
  • 使用useEffect获取数据
//useState 使用状态值,第一个 hook
//1.引入useState  钩子
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
  //将获取数据封装为函数
  function getData() {
    return axios.get("http://www.51houniao.com/product/product/guessYouLike").then(res => {
      return res;
    })
  }

  //相当于挂载
  useEffect(async () => {
    const data = await getData();
    console.log(data);
  }, [])
  return (
    <div>
      <h2>获取数据</h2>
    </div>
  )
}
export default App;

你可能感兴趣的:(React,Hooks,useEffect)