Hooks基础-------useEffect基本用法

useEffect 可以在组件渲染后实现各种不同的副作用。通过使用这个 Hook,你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。

useEffect告诉react在渲染后要去做什么,就是渲染后执行里面的函数,且执行的较晚

useEffect(()=>{
    //平常执行的函数
    return()=>{
        //点击销毁后执行的函数
    }
},[]) //[]表示根据什么而改变的

1、只有一个参数时

相当于componentDidMount和componentDidUpdate

useEffect(() => {
    console.log("count", count);
});

2、有两个参数时

2-1 第二个参数是[]时,相当于componentDidMount

useEffect(() => {
    console.log("num", num);
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

2-2 第二个参数有值时,只有当[]中的值改变时useEffect才会生效

useEffect(() => {
    console.log("count", count);
    console.log("num", num);
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [num]);

3、卸载

useEffect(() => {
    console.log("login");
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // 当props.friend.id发生变化时,将会先进行清除工作
    return () => {
      console.log("logout");
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id);
    };
}, [props.friend.id]);

整个过程就像

// Mount with { friend: { id: 100 } } props
ChatAPI.subscribeToFriendStatus(100, handleStatusChange);     // 首次加载运行第一个 effect
​
// Update with { friend: { id: 200 } } props
ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // 先清除上一个 effect
ChatAPI.subscribeToFriendStatus(200, handleStatusChange);     // 再运行下一个 effect
​
// Update with { friend: { id: 300 } } props
ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // 先清除上一个 effect
ChatAPI.subscribeToFriendStatus(300, handleStatusChange);     // 再运行下一个 effect
​
// Unmount
ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // 清除最后一个 effect

这是一个最基本的useEffect例子,利用useState替代了类组件里面的componentDidMount和componentDidUpdate

function Example() {
  const [count, setCount] = useState(0);
​
  //只要有重新渲染就会执行useEffect
  useEffect(() => {
    //比如这个document.title是函数作用域之外的事务,或者打开数据库,调用其他的函数
    //没有第二个参数,所以每次重新渲染都会被执行
    document.title = `Example ${count} times`;
    console.log("Example click");
  });
​
  //第一个参数告诉react渲染完后要去执行什么内容,第二个参数告诉react什么时候执行
  //当第二个参数执行的时候才会发生变化,[]只执行一次,就是react渲染完后执行的那一次,相当于componentDidMount
  //之后再点击按钮进行重新渲染就不会影响到它
  useEffect(() => {
    console.log("Example render once");
  }, []);
​
  return (
    <div>
      <p>click {count}</p>
      <button onClick={() => setCount(count + 1)}>click me</button>
      <button onClick={() => setCount(count)}>不变</button>
    </div>
  );
}

以下代码是用class表示的

class Example1 extends React.Component {
  state = { count: 1 };
​
  componentDidMount() {
    document.title = `Example1 clicked ${this.state.count} first`;
    console.log(document.title);
  }
​
  componentDidUpdate() {
    document.title = `Example1 clicked ${this.state.count} time2`;
    console.log(document.title);
  }
​
  render() {
    return (
      <div>
        <p>clicked {this.state.count}</p>
        <button onClick={() => this.setState({ count: this.state.count + 2 })}>
          click me
        </button>
      </div>
    );
  }
}

相比而言,useEffect简单了许多

案例一

function GithubUsers() {
  const [users, setUsers] = useState([]);
​
  useEffect(() => {
    axios({
      type: "GET",
      url: "https://api.github.com/users",
    }).then((response) => {
      setUsers(response.data);
    });
  }, []);
​
  return (
    <div className="section">
      {/* 渲染了两次是因为,第一次函数全部运行一遍,先输出一次,第二次因为setUser重新渲染又执行了一次 */}
      {console.log("GithubUsers 我渲染了两次")}
      {users.map((user) => (
        <div key={user.id} className="card">
          <h5>{user.login}</h5>
        </div>
      ))}
    </div>
  );
}

完整案例

import React from 'react'
import { useState, useEffect } from 'react';
​
const ChatAPI = {
  handle: null,
  isOnline: false,
  login: function () {
    this.isOnline = true
    //这里面的函数是执行订阅完后传回来的函数 handleStatusChange
    if (this.handle) this.handle({ isOnline: true })
  },
  logout: function () {
    this.isOnline = false
    if (this.handle) this.handle({ isOnline: false })
  },
  subscribeToFriendStatus: function (id, handle) {
    console.log(`订阅 用户id:${id}`);
    //接收函数
    this.handle = handle
  },
  unsubscribeFromFriendStatus: function (id) {
    console.log(`清理 用户id:${id}`);
    this.handle = null
  },
}
​
​
function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null)
​
  //设置在线还是不在线的一种状态
  function handleStatusChange(status) {
    setIsOnline(status.isOnline)
  }
​
  //条件发生变化时。先会清理掉之前的effect,再执行下一个effect
  useEffect(() => {
    //函数执行完后subscribeToFriendStatus将会被调用
    console.log('login');//刷新页面后会直接显示
​
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange)
    //返回的函数在组件卸载的时候执行
    return () => {
      console.log('logout');//点击卸载组件后才会显示
​
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange)
    }
  }, [props.friend.id])//仅当id改变时,才会重新订阅
​
  if (isOnline === null) {
    return 'loading..'
  }
  return (
    <div>
      {console.log('FriendStatus 刷新')}
      {isOnline ? 'Online' : "Offline"}
    </div>
  )
}
​
function App() {
  const [show, setShow] = useState(true)
  const [count, setCount] = useState(0)
  const [userId, setUserId] = useState(1)
  return (
    <div>
      userId:{userId} <br />
      计数器:{count} <button onClick={() => setCount(count + 1)}>改变计数器</button> <br />
      {show ? <FriendStatus friend={{ id: userId, name: 'tom' }} /> : null}
      <button onClick={() => setShow(!show)}>显示/关闭</button>
      <button onClick={() => setUserId(userId + 1)}>userId+1</button>
​
      <button onClick={() => ChatAPI.login()}>登录</button>
      <button onClick={() => ChatAPI.logout()}>退出</button>
    </div>
  )
}
​
export default App

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值