无需订阅即可读取 React Context 值,例如 Redux 的 store.getState()

Posted

技术标签:

【中文标题】无需订阅即可读取 React Context 值,例如 Redux 的 store.getState()【英文标题】:Read React Context value without subscription like Redux's store.getState() 【发布时间】:2020-09-18 22:14:03 【问题描述】:
const UsersStateContext = React.createContext( [user:1,user:2,user:3] );

function getState()
  return UsersStateContext._currentValue;

经过几个小时的搜索,我找到了官方不支持的这种方法。有没有像 Redux 的 store.getState() 那样让 React 钩子只读取当前状态而无需订阅的解决方案?

或者这种方法在生产中使用安全吗?

【问题讨论】:

这能回答你的问题吗? How to get the data from React Context Consumer outside the render 有人很好地解释了“没有组件的上下文是没有意义的”。但是删了。例如,Users State Context Provider 中的按钮由 Context 中的用户数据呈现,按下它后,它会使用该用户数据从另一个 Context(与其呈现无关)中提取数据,并将两者发送到外部的组件树用户状态上下文提供程序树。所以即使它使用上下文数据,也有组件不受上下文变化的影响。我们应该如何解决这个问题? 所以如果我可以读取一个值,那就没问题了。 (不是在寻找 React.Memo 解决方案) 你找到了一些好的解决方案吗? 不幸的是。正如下面的答案所示,我将相同的数据同步保存在一个全局变量中,并在需要时调用它。 【参考方案1】:

简短回答:在生产环境中不安全,您可以维护一个全局变量

这个“hack”完全就像从全局变量中读取。当全局变量更新时,您的组件无法得到通知

在此处查看有关全局变量的说明:Why need useRef to contain mutable variable but not define a variable outside the component function?

let counter = 0;

const Component = () => 
 /* 
    On changing the counter value, the component won't get re-rendered with its new value.
 */
  console.log(counter);
  return <></>

有没有像 Redux 的 store.getState() 那样让 React 钩子只读取当前状态而无需订阅的解决方案?

store.getState() 返回 store 的 reducer 返回的最后一个值。这正是您对UsersStateContext._currentValue 的预期行为,如果您想感觉更安全,您可以按照上述方式维护一个全局变量。


官方的方式是通过消费来订阅上下文,例如useContext:

const value = useContext(MyContext);

【讨论】:

谢谢丹尼斯!我想我需要维护一个全局变量或返回redux。有些组件通过上下文数据进行渲染,但对数据更改不感兴趣。甚至有时我的服务功能需要访问这些数据。订阅一个上下文来读取一个值看起来并不聪明。我试图删除 redux 依赖,但我的代码变成了意大利面条。 “订阅一个上下文来读取一个值看起来并不聪明。”确实如此,您将无法仅使用提到的store.getStore() 来做到这一点。 如果您有具体示例,请随时提出新问题。 实际上,我想要的只是从存在的对象中读取单个值。大声笑

以上是关于无需订阅即可读取 React Context 值,例如 Redux 的 store.getState()的主要内容,如果未能解决你的问题,请参考以下文章

React Context中的useContext解析及使用

React的Context对象解决props传递数据的烦恼!

无需订阅即可使用 Laravel Cashier 一次性付款

无需注册即可恢复非续订订阅的交易

React API

React 组件通信之发布订阅模式