首页 > 其他分享 >React Hook 之 Effect :同步与外部系统的数据

React Hook 之 Effect :同步与外部系统的数据

时间:2023-12-26 22:57:41浏览次数:38  
标签:function useEffect return Effect React Hook 组件 isPlaying

有时组件中的数据需要与外部系统的数据或操作同步,React提供了Hook Effect。

Effect 会在组件渲染后运行一些代码,以便将组件与 React 之外的某些系统同步,包比如浏览器 API、第三方小部件,以及网络请求等。

如以下的video播放器的简单加载:

// 声明 Effect
import { useEffect, useRef } from 'react';
/*
* src:来自父组件的props,视频资源的地址
* isPlaying:来自父组件的props,视频是否播放,boolean值
* */
function VideoPlayer({ src, isPlaying }) {
    const ref = useRef(null);
    /*
        Effect 依赖 isPlaying prop 控制逻辑
        如果 isPlaying 在上一次渲染时与当前相同,跳过运行 Effect
        如果不添加依赖,组件每次渲染后都会执行 Effect
        如果依赖为[],组件只在挂载后执行 Effect

    */
    useEffect(() => {
        // 组件渲染之后执行以下代码
        // 否则video dom尚未渲染,不存在play() 和 pause()方法
        if (isPlaying) {
            ref.current.play();
        } else {
            ref.current.pause();
        }
    }, [isPlaying]);
    // 同步到 React state 的“外部系统”是浏览器媒体 API
    return <video ref={ref} src={src} loop playsInline />;
}
export default function App() {
    const [isPlaying, setIsPlaying] = useState(false);
    return (
        <>
            <button onClick={() => setIsPlaying(!isPlaying)}>
                {isPlaying ? 'Pause' : 'Play'}
            </button>
            <VideoPlayer
                isPlaying={isPlaying}
                src="water.mp4"
            />
        </>
    );
}

有时 Effect 需要指定如何停止、撤销,或者清除它的效果。例如,“连接”操作需要“断连”,“获取”既需要“取消”也需要“忽略”。这时候就需要使用清理函数。

每次重新执行 Effect 之前,React 都会调用清理函数;组件被卸载时,也会调用清理函数。

严格模式时,在开发环境下,Effect出现额外的执行,是 React 正在调试你的代码。

通常的解决办法是实现清理函数,停止或撤销 Effect 正在执行的任何操作。

在生产环境下,Effect只会执行一次。

如下面的模拟聊天室功能:

App.js

import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
      //建立连接
    const connection = createConnection();
    connection.connect();
      //清理函数,断开连接
    return () => connection.disconnect();
  }, []);
  return <h1>欢迎来到聊天室!</h1>;
}

chat.js

export function createConnection() {
  // 连接的示例
  return {
    connect() {
      console.log('连接中……');
    },
    disconnect() {
      console.log('连接断开。');
    }
  };
}

Effect应用举例:

1、订阅事件 

如果 Effect 订阅了某些事件,清理函数应该退订这些事件:

useEffect(() => {
  function handleScroll(e) {
    console.log(window.scrollX, window.scrollY);
  }
    //页面滚动事件
  window.addEventListener('scroll', handleScroll);
    //清理页面滚动事件
  return () => window.removeEventListener('scroll', handleScroll);
}, []);

2、触发动画 

如果 Effect 对某些内容加入了动画,清理函数应将动画重置:

useEffect(() => {
  const node = ref.current;
  node.style.opacity = 1; // 触发动画
  return () => {
    node.style.opacity = 0; // 重置为初始值
  };
}, []);

3、获取数据 

如果 Effect 将会获取数据,清理函数应该要么终止数据获取操作,要么忽略其结果:

useEffect(() => {
  let ignore = false;

  async function startFetching() {
    const json = await fetchTodos(userId);
      //不忽略结果,更新数据
    if (!ignore) {
      setTodos(json);
    }
  }

  startFetching();

  return () => {
    ignore = true;
  };
}, [userId]);

还有一些情形看似需要使用 Effect 实则并不需要,比如:初始化应用时,某些逻辑只需要在应用程序启动时运行一次。比如,验证登陆状态和加载本地程序数据,可以将其放在组件之外: 

if (typeof window !== 'undefined') { // 检查是否在浏览器中运行
  checkAuthToken();
  loadDataFromLocalStorage();
}

function App() {
  // ……
}

 

标签:function,useEffect,return,Effect,React,Hook,组件,isPlaying
From: https://www.cnblogs.com/wuxxblog/p/17927254.html

相关文章

  • 【教程】React Native 应用中的代码混淆与安全性管理
    ​混淆是指对源代码进行加密、重命名等操作,以增加代码的复杂度,使其难以理解和反编译。在ReactNative中,混淆可以通过以下步骤实现:1.将JavaScript源代码转换为基于本机平台的二进制代码,可以使用工具如MetroBundler或babel进行转换。2.使用混淆工具,例如ipaguard(iOS平台),来对生......
  • 【代码混淆】react-native 代码混淆
    ​ 【代码混淆】react-native代码混淆 使用reactnative开发app,实现代码混淆的操作。无论是加密还是运行时虚拟机,最后都可以通过执行时调试把代码反向生成出来原来的代码,虽然能抵御低端的黑客攻击,但是对高端黑客却形同虚设。代码混淆是通过修改源代码结构和变量名,使得代码......
  • React拖拽效果实现
    基于React的拖拽效果Demo一个基于React的拖拽功能实现的Demo.两个关键点1,draggable属性2,drag事件draggable属性img标签默认是支持拖拽的,当时其他HTML标签,想要其拖动的话,需要为其添加draggable="true"属性drag事件drag相关的事件有:ondragstart......
  • 【Python微信机器人】第六七篇: 封装32位和64位Python hook框架实战打印微信日志
    目录修整目前的系列目录(后面会根据实际情况变动):在windows11上编译python将python注入到其他进程并运行注入Python并使用ctypes主动调用进程内的函数和读取内存结构体调用汇编引擎实战发送文本和图片消息(支持32位和64位微信)允许Python加载运行py脚本且支持热加载利用......
  • JS逆向快速定位关键点之通用hook脚本
    大部分网站都会对关键参数进行加密,JS逆向时,我们首要任务是定位参数具体的加密逻辑。常见方式包含:关键字搜索、堆栈调试、XHR及事件监听、AST内存漫游、JSHook注入等本篇文章以JSHook注入为切入点,在做JS逆向往往需要定位到一些关键参数位置去分析,比如Cookie、Sign、Toke......
  • From Bench to Bioreactor: Scaling Up Bioprocesses for Commercial Success
    1.背景介绍Bioprocessesarefundamentaltomanyindustries,includingpharmaceuticals,foodandbeverage,andbioenergy.Astheseindustriesgrow,theneedtoscaleupbioprocessesbecomesincreasinglyimportant.However,scalingupbioprocessesisnotatrivi......
  • 组合式函数hook
    什么是“组合式函数”?在Vue应用的概念中,“组合式函数”(Composables)是一个利用Vue的组合式API来封装和复用有状态逻辑的函数。类似与vue2中mixin(混入)当构建前端应用时,我们常常需要复用公共任务的逻辑。例如为了在不同地方格式化时间,我们可能会抽取一个可复用的日期格式......
  • react_hooks系列 useMemo
    一、概念和作用​写在函数式组件里的“函数调用代码”。如果函数式组件重新渲染时,每次都会执行“调用函数的代码”。如果不是必须的,那么就是性能的浪费。useMemo就是解决这个问题的。即:useMemo是防止不必要的的函数调用。​文字描述总是让你很难理解。很抽象。还是要看代码的......
  • 5.10 Windows驱动开发:摘除InlineHook内核钩子
    在笔者上一篇文章《内核层InlineHook挂钩函数》中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能,此类功能的实现一般可在应用层进行,而驱动层只需要保留一个读写字节的函数即可,将复杂的流程放在应用层实现是一个非常明......
  • React 的 Suspense 和 ErrorBoundary 还有这种关系?
    Suspense组件想必大家都用过,一般是和React.lazy结合用,用来加载一些异步组件。比如这样一个组件://src/Aaa.jsxexportdefaultfunctionAaa(){return<div>aaa</div>}就可以在另一个组件里用lazy+Suspense异步加载:importReact,{Suspense}from'react';const......