简体   繁体   English

如何在自定义钩子的回调中保持更新的反应上下文值

[英]How to keep updated react context value inside a callback in a custom hook

I have a userContext wrapped my app, I have a custom hook useAnalytics used to send analytics events and I have a Login component which performs the log in and changes the user value in the context and send an event.我有一个 userContext 包装了我的应用程序,我有一个自定义钩子 useAnalytics 用于发送分析事件,我有一个登录组件,它执行登录并更改上下文中的用户值并发送事件。

My problem is when I do a setUser inside my Login component the updating user data is not reflected in useAnalytics hook which it sends always the user data in every event我的问题是,当我在登录组件中执行 setUser 时,更新用户数据未反映在 useAnalytics 挂钩中,它始终在每个事件中发送用户数据

Here a sandbox: https://codesandbox.io/s/romantic-perlman-wzxti?file=/src/Login.js You can open the console and see the results after clicking SEND这里有一个沙箱: https : //codesandbox.io/s/romantic-perlman-wzxti? file =/ src/ Login.js点击SEND就可以打开控制台查看结果

I know this is probably an anti-pattern but it would be good to know why I get this behavior我知道这可能是一种反模式,但最好知道我为什么会出现这种行为

Thanks!谢谢!

The problem is that all set states are async, while the sending of the event is in sync.问题是所有设置的状态都是异步的,而事件的发送是同步的。 So you dispatch the change, send the analytic and after a timeout, the state is updated.因此,您发送更改,发送分析,并在超时后更新状态。 There are 2 main ways to fix this.有两种主要方法可以解决此问题。

  1. Set a timeout to wait for react to update the state and push the analytic after the state is updated:设置超时以等待 react 更新状态并在状态更新后推送分析:
setUser({ type: "login", data: { user: "pippo" } });
setTimeout(sendEvent, 16);
  1. Send the analytic with a middleware:使用中间件发送分析:

Add a middleware to intercept all reducer changes and push those to the analytic without the hook itself.添加一个中间件来拦截所有 reducer 更改并将它们推送到分析中,而无需挂钩本身。 This will guarantee that you get all changes that you need to track by checking for the action.type and sending the new data from action.payload.这将保证您通过检查action.type并从 action.payload 发送新数据来获得需要跟踪的所有更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM