React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文

这篇具有很好参考价值的文章主要介绍了React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、ref 转发解决什么问题

1、使用自定义组件时,实现外层组件对原始组件(TextInput)的操作

外层组件使用 ref 属性

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

子组件使用 forwardRef 包裹

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

2、函数式组件对外暴露实例方法(cusomFocus)

子组件

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

父组件如图一所示

二、memo 解决什么问题?

1 、 避免多余渲染

问题:每次点击按钮都会导致 InfoView 组件发生重绘,即使每次 setInfo 都是一样的内容也是如此,这就是多余的

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

优化:给函数式组件 InfoView 外面包裹上 React.memo() ,比较前后 props 的值来决定是否发生重绘。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

2、避免重复计算、重复创建对象

1、useMemo 缓存数据

在没有使用useMemo 时,仅改变组件中 showType 的状态,会导致组件重绘重新计算合计,而状态的变更并不会导致合计的计算结果发生变化,此时的计算就是多余的,就可以使用 useMemo 缓存函数计算结果,仅依赖条件 data 发生变化时才重新计算。useMemo 返回值是一个值而不是一个方法。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

2、useMemo 缓存 UI 渲染

在合计这个 UI 模块,当数据源 data 不会发生改变的情况下,整个 UI 结构也是固定的,就可以直接缓存整个组件。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

3、useCallback 缓存回调函数

问题:

  • 在 1 处如果 view 组件重新渲染一次,每次都是会生成一个新的 onItemPress 函数对象。
  • 在 2 处列表每生成一个 Item 组件就都会创建一个新的函数对象。
  • 这些都是多余,没必要,无意义的操作。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

优化:使用 useCallback 解决两层重复创建函数对象的问题

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

ps:
因为 onPress 只能接受无参的函数,无法直接调用,所以可以将函数改造成一个高阶函数,这样就返回了一个无参的函数。

    const onItemPress = useCallback((item: any, index: any) => {
        return () => {
            console.log(`${item + index}`);
        }
    }, [])

三、高阶组件&高阶函数

高阶组件解决什么问题?

使用 HOC高阶组件解决横切关注点问题,使得组件功能更加单一,组件逻辑服务组件UI,从而降低耦合性,增强组件的复用性。

横切点关注点问题:
对于一个现有的组件而言,希望能在这个组件的某一个横切点去做一些事情,比如多渲染一个额外的视图,或者在组件的生命周期的某个节点去做一些事情,但是这个事情本身是和原始组件没有关系的。

什么是高阶函数?

如果一个函数接受的参数为函数,或者返回值是一个新函数,则该函数就是高阶函数。

setTimeout(() => {},1000);
array.filter((item, index) => item === target);
Promise...

什么是高阶组件?

如果一个组件的参数是组件,返回值是一个新组件,则该组件就是高阶组件。

高阶组件应用场景一(解耦):

如图所示,此处实现了一个添加按钮在页面右下角

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

1、如果不使用高阶组件能不能达到同样的效果?

答案是能,只需要在详情页面加一个按钮也能达到同样的效果

缺点:

  • 所有的样式效果,功能模块都集中在一个页面里面了,即使有很多功能是与此页面的职责毫不相关,比如:页面中的添加按钮只是一个入口,与详情页是不相关的,它可以是在任何页面中显示,只是现在我们把它放到了详情页。这就是一种耦合,在详情页中添加这样一些与职责不相干的代码就是不合适的。
  • 假设有很多个页面都需要这样的添加按钮,就需要写很多重复代码在不同的页面。

2、使用高阶组件就能有效解决这些问题。

将特定的样式,逻辑,全都写在高阶组件中,使用时只需要包裹一下需要使用高阶组件实现的特定的功能的组件,就能将高阶组件特定的功能赋予被包裹的组件。

而且通过简单的包裹就能有效的提高代码复用率。

// 高阶组件函数,接受一个泛型参数 T,表示组件类型,以及一个字符串参数 type
export default <T extends IReactComponent>(
  OriginView: T | React.FC,  // OriginView 参数可以是实现了 IReactComponent 接口的组件或函数式组件
  type: string,  // type 参数是一个字符串
): T => {
  // 定义高阶组件内部的函数组件 HOCView
  const HOCView = (props: any) => {
    useEffect(() => {
      // 空的 useEffect 钩子,可用于添加其他副作用逻辑
    }, []);

    return (
      <>
        {/* 渲染传入的原始组件,通过 {...props} 将所有 props 传递给原始组件 */}
        <OriginView {...props} />
        
        {/* 添加一个 TouchableOpacity 组件,当点击时执行 console.log 输出信息 */}
        <TouchableOpacity
          style={styles.addButton}
          onPress={() => {
            console.log('onPress ...', type);
          }}>
          <Image style={styles.addImg} source={icon_add} />
        </TouchableOpacity>
      </>
    );
  };

  // 将 HOCView 转换为指定的泛型类型 T,并返回
  return HOCView as T;
};

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

高阶组件使用场景二:

假设有一个需求:实现首页设备信息上报。(类似还有页面弹窗、申请系统权限等)

很简单的实现是:直接在首页页面的生命周期中发送请求,提交设备信息。

这里需要思考的是,上报设备信息这件事与首页的职能有关系吗?其实是没有关系的,只是这件事情刚好在首页发生了,在其他任何的页面上报设备信息都行,就这件事而言无论发生在哪里都是没有任何区别的。

从这个角度出发,把上报的代码直接写在首页就是不太合适的,这就出现了代码耦合,需要其解耦出去。

此处解耦的方式可以使用 hook 实现,也可以使用高阶组件实现。

高阶组件本质也是组件所以也有它自己的生命周期。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

注意事项

1、不要改变传入的原始组件的原型

需要做的是在原始组件的基础上额外附加一些东西,不要对原始组件做任何改动

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

2、必要的话也是可以传入多个参数

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

四、Context 上下文

Context解决什么问题?

在一个典型的反应应用中,数据是通过 props 属性逐层传递,这种做法对于某些数据而言是极其繁琐的 (如:登陆信息,用户界面主题) ,这些数据应用中许多组件都需要,而Context 上下文提供了一种在组件间共享值的方式,而不必显式地通过组件树逐层传递。

这样就可以对一些全局数据进行直接共享

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js
使用流程:

1、创建了一个名为ThemeContext的Context对象,用于在React应用程序中共享主题(theme)相关的数据,数据类型为字符串,并且默认值为’dark’。

import {createContext} from 'react';
export const ThemeContext = createContext<string>('dark');

2、使用<ThemeContext.Provider>包裹根节点,这样组件树中的任何组件都可以通过Context访问backgroundStyle这个值。

React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文,React Native,React,react native,react.js

Provider 这个命名惯例通常是为了表示在React中充当数据提供者的组件。

这是一种常见的命名模式,在React中,Context API中的数据提供者通常被称为 <SomeContext.Provider>,其中 SomeContext 是你创建的Context对象的名称。

这个命名约定有几个好处:

  1. 明确的角色:使用 Provider 作为后缀,清晰地表明了组件的作用是提供数据给内部和子组件,有助于理解组件的用途。

  2. 语义化:可以根据组件的名称推断出它的作用,语义化的命名有助于代码的可维护性和可读性。

  3. 一致性:这种命名约定是React社区的共识,有助于减少混淆和提高协作的效率。

总之,Provider 命名约定是React中的一种通用惯例,用于标识充当数据提供者的组件,有助于更清晰地组织和理解React应用程序的组件结构。

3、在应用的任何一个页面,都能使用 useContext 取到值

import React, {useContext} from 'react';
import {ThemeContext} from 'src/component/ThemeContext';
const HomeScreen: React.FC = () => {
  const theme = useContext(ThemeContext);
  return (<View></View>)
}

注意事项文章来源地址https://www.toymoban.com/news/detail-810738.html

  • 因为Context本质上就是全局变量,大量使用Context会导致组件失去独立性,使组件复用性变差。
  • 对于常规的组件间传值先考虑组件组合、状态管理、单例导出等方式,不要过度使用Context。

到了这里,关于React Native Ref转发/Memo缓存/HOC高阶组件/Context上下文的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • react高阶成分(HOC)

    使用React函数式组件写了一个身份验证的一个功能,示例通过高阶组件实现的一个效果展示: 在这个示例中,withAuthentication 是一个高阶组件,它接受一个函数式组件 WrappedComponent 作为参数,并返回一个新的函数式组件 WithAuthentication。在 WithAuthentication 组件内部,我们使用了

    2024年01月24日
    浏览(35)
  • React性能优化之memo缓存函数

    React是一个非常流行的前端框架,但是在处理大型应用程序时,性能可能会成为一个问题。为了解决这个问题,React提供了一个称为memo的功能,它可以缓存函数并避免不必要的重新渲染。 memo是React中的一个高阶组件(HOC),它接收一个组件并返回一个新的组件。这个新组件具

    2024年02月11日
    浏览(32)
  • 高阶组件/react组件复用

                               

    2024年02月13日
    浏览(31)
  • 【React】组件性能优化、高阶组件

    React更新机制 ◼ React在props或state发生改变时,会调用React的render方法,会创建一颗不同的树。 ◼ React需要基于这两颗不同的树之间的差别来判断如何有效的更新UI: ​  如果一棵树参考另外一棵树进行完全比较更新,那么即使是最先进的算法,该算法的复杂程度为 O(n³),其

    2024年01月23日
    浏览(34)
  • react-高阶组件

    高阶组件( Higher-Order Component,HOC )是一个以 组件作为参数 ,返回一个 新组件 的 函数 。 高阶组件最大的特点就是 复用组件逻辑 高阶组件本身并不是 React 的 API,而是React组件的一种设计模式,一种组件重用的 高级技巧 高阶组件是一个 函数 ,接收要包装的组件,返回增

    2024年02月07日
    浏览(30)
  • React的高阶组件详解

    高阶组件基本介绍 什么是高阶组件呢? 在认识高阶组价之前, 我们先来回顾一下什么是高阶函数? 相信很多同学都知道(听说过?),也用过高阶函数 高阶组件和高阶函数它们非常相似的 高阶函数的定义, 至少满足以下条件之一: 接受一个或多个函数作为参数; 返回一个新的函数

    2024年02月01日
    浏览(41)
  • React Native 桥接组件封装原生组件属性

    自定义属性可以让组件具备更多的灵活性,所以有必要在JS 层通过自定义属性动态传值。 因为 ViewManager 管理了整个组件的行为,所以要新增组件属性也需要在这里面(如 InfoViewManager)进行定义。 1、在InfoViewManager 中定义一个 setAvatar 方法。 @ReactProp 是 React Native 中的注解,用

    2024年01月21日
    浏览(33)
  • React - 你使用过高阶组件吗

    难度级别:初级及以上                                 提问概率:55%  高阶组件并不能单纯的说它是一个函数,或是一个组件,在React中,函数也可以做为一种组件。而高阶组件就是将一个组件做为入参,被传入一个函数或者组件中,经过一定的加工处理,最

    2024年04月16日
    浏览(38)
  • 【react】使用context进行跨级组件数据传递

    官方文档:使用 Context 深层传递参数、useContext 应用:无需为每层组件手动添加 props,能狗在组件树间进行数据传递的方法。 1、创建context ContextProvider.tsx: 要更新 context,请将其与 state 结合。在父组件中声明一个状态变量,并将当前状态作为 context value 传递给 provider。 上述写

    2024年01月25日
    浏览(32)
  • react通过ref获取函数子组件实例方法

    在react16之后带来了hooks之后,确实方便了很多组件开发,也加快了函数式编程的速度,但是当你通过useRef获取子组件的时候,又恰好子组件是一个函数组件,那么将会报一个错误:报这个错误的主要原因是函数组件没有实例对象,所以你没办法通过ref获取子组件实例  Warnin

    2024年02月11日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包