【问题标题】:Use React Context outside a react component在反应组件之外使用反应上下文
【发布时间】:2020-01-01 00:16:54
【问题描述】:

新的 React Context API 非常棒,但是我似乎总是想方设法在 React 组件之外访问它。当你在 React 函数组件或 React 类组件中时,一切都很好,但是当你需要从上下文中读取或重置一个值(例如由于在 fetch 函数中发生的异步操作),没有简单的方法可以做到这一点..

那么,有没有办法在 React 组件之外访问 React Context Consumer 中的值?

后期编辑: 我继承了一个基于 Redux 的项目并慢慢过渡出来。在动作创建者中,我有一个清除商店内容的注销功能:

export const logoutRequest = () => dispatch => {
  navigate('Welcome')
  // Reset apollo data
  client.resetStore()
  persistor.purge()
  // Reset context api data HERE
  //
}

我可以轻松地在调用注销请求的组件中创建一个使用者,但这发生在 3 个不同的组件中,我不想在那里复制代码..

【问题讨论】:

  • 您能举个例子吗?不是很清楚,为什么要在组件之外访问它。
  • 但是,在组件之外访问它到底意味着什么?没有提供者,以祖先组件的形式,它是无用的。所以......在组件之外意味着在没有提供者的情况下访问上下文,这会让你......究竟是什么?
  • 你能把你的 fetch 函数放在拥有上下文提供者的组件中吗?或者使上下文成为一个对象,并提供设置函数来改变任何必要的状态?我只是想不出 React 应用程序中有很多情况需要在组件之外有代码,这绝对不应该经常发生。如果您可以发布您遇到此问题的某些组件的代码,我们可以为您提供更具体的建议。
  • 添加了更具体的例子..但是,我认为这里的用例不太重要..

标签: javascript reactjs react-native


【解决方案1】:

你最终会在组件中调用logoutRequest() 对吧?如果你不想重复代码,你可以创建一个自定义钩子:

const useLogout = () => {
  const resetContext = React.useContext(SomeContext);
  const logoutRequest = () => dispatch => {
    navigate('Welcome');
    client.resetStore();
    persistor.purge();
    resetContext();
  };
  return logoutRequest;
}

然后你可以在你的组件中调用const logoutRequest = useLogout()。 你也可以对异步操作做类似的事情。

【讨论】:

    【解决方案2】:

    React 上下文仅在 UI 可用时可用。这意味着在后台任务中您无法访问它。但这并不意味着您不能在组件“外部”访问它。

    我将举一个例子,你可以在组件之外使用它,也不能在组件之外使用它:

    • 不可能:您有一个计划的后台任务(使用操作系统机制)来做一些工作(可能会获取一些东西),通常会发生操作系统只唤醒应用程序的一部分(假设应用程序处于退出状态)处理后台任务,因此不会加载 UI(并干扰用户当前正在执行的操作) - 所以这里的上下文将不可用
    • 可能:您有一个 Web 套接字来侦听来自服务器的事件(可能是聊天),并且当事件到达时您希望更新上下文。这是可能的,因为 Web 套接字不能在后台运行(当 UI 被用户/系统抛弃时 - 退出状态)以反应本机(特别是)。 这样做的方法是用一个类包装套接字事件处理程序,并使用上下文调度函数(保存为类的私有属性)对其进行初始化。在同一范围内,处理程序可以访问此私有属性以更新上下文。

    对背景状态的更深入解释:

    你应该区分 3 个背景状态

    1. 退出 - 应用程序从未打开(自上次手机启动以来)或被系统丢弃以释放一些资源。在这种状态下,应用程序不允许执行任何代码,只有当它被系统调用时(例如计划任务)。
    2. 背景 - 应用程序已打开但失去了用户的焦点(例如切换到另一个应用程序)。 UI 仍在内存中并且可用(包括上下文),并且所有应用程序的代码都可以继续运行。在 iOS 上,这种状态是不可能的,在 Android 上,这种状态在有限的时间内是可能的,通常之后操作系统会退出应用程序。
    3. 前景 - 应用程序打开并处于用户的焦点中。在这里几乎一切皆有可能。

    【讨论】:

      【解决方案3】:

      不,你不能。更新上下文的唯一方法是更改​​发送到 Context.Provider 的值。

      对于异步操作,通常会将结果保存在根组件(或呈现提供程序的组件)中并更改发送的值。或者你可以在上下文中创建一个函数,如下所示https://reactjs.org/docs/context.html#updating-context-from-a-nested-component

      【讨论】:

        猜你喜欢
        • 2017-08-24
        • 2016-10-12
        • 1970-01-01
        • 2021-09-24
        • 2019-07-27
        • 1970-01-01
        • 2019-03-06
        • 2021-01-26
        • 2019-12-20
        相关资源
        最近更新 更多