在React中,我如何在我的useEffect代码运行后才返回children prop(同步行为)?

huangapple go评论98阅读模式
英文:

How can I return children prop in react only after my useEffect code runs. (synchronous behaviour)

问题

我正在尝试为我的axios请求创建一个拦截器包装器,以处理JWT令牌。

我想要的是先在useEffect块内运行拦截器代码,然后返回children,以便children带着新的访问令牌返回,最终完成成功的API调用。但是实际上我得到的是,它返回的是旧的JWT令牌,并且API调用会使用过期的令牌导致错误。

我还尝试添加一个状态,如下:

  1. const [isSet, setIsSet] = useState<boolean>(false);
  2. // ...
  3. setIsSet(true)
  4. // ...
  5. return isSet && children;

但是 TypeScript 不允许我这样做。

如何解决这个问题?

英文:

I am trying to create axios interceptor wrapper for my axios request to handle JWT tokens.

What I want is to run the interceptor code first inside the useEffect block and then return children so that the children returns with new access token and eventually a successfull api call. but instead what I am getting is, it is returning with the old jwt token and the api call happens with an expired token resulting to an error.

  1. const AxiosPrivateInterceptor: FC&lt;IProps&gt; = ({ children }) =&gt; {
  2. const { user } = useAppSelector(selectAuthUser);
  3. const refresh = useRefreshToken();
  4. useEffect(() =&gt; {
  5. const requestIntercept = axiosPrivate.interceptors.request.use(
  6. (config: AxiosRequestConfig) =&gt; {
  7. config.headers = config.headers ?? {};
  8. if (!config?.headers[&quot;Authorization&quot;]) {
  9. config.headers[&quot;Authorization&quot;] = `Bearer ${user?.accessToken}`;
  10. }
  11. return config;
  12. },
  13. (error) =&gt; Promise.reject(error)
  14. );
  15. const responseIntercept = axiosPrivate.interceptors.response.use(
  16. (response) =&gt; response,
  17. async (error) =&gt; {
  18. const prevRequest = error?.config;
  19. if (error?.response.status === 403 &amp;&amp; !prevRequest?.sent) {
  20. prevRequest.send = true;
  21. const newToken = await refresh();
  22. const accessToken = newToken.accessToken;
  23. prevRequest.headers[&quot;Authorization&quot;] = `Bearer ${accessToken}`;
  24. return axiosPrivate(prevRequest);
  25. }
  26. return Promise.reject(error);
  27. }
  28. );
  29. return () =&gt; {
  30. axiosPrivate.interceptors.request.eject(requestIntercept);
  31. axiosPrivate.interceptors.response.eject(responseIntercept);
  32. };
  33. }, [user, refresh]);
  34. return children;
  35. };
  36. I also tried to add a state like this :
  37. const AxiosPrivateInterceptor: FC&lt;IProps&gt; = ({ children }) =&gt; {
  38. const { user } = useAppSelector(selectAuthUser);
  39. const refresh = useRefreshToken();
  40. const [isSet, setIsSet] = useState&lt;boolean&gt;(false);
  41. useEffect(() =&gt; {
  42. const requestIntercept = axiosPrivate.interceptors.request.use(
  43. (config: AxiosRequestConfig) =&gt; {
  44. config.headers = config.headers ?? {};
  45. if (!config?.headers[&quot;Authorization&quot;]) {
  46. config.headers[&quot;Authorization&quot;] = `Bearer ${user?.accessToken}`;
  47. }
  48. return config;
  49. },
  50. (error) =&gt; Promise.reject(error)
  51. );
  52. const responseIntercept = axiosPrivate.interceptors.response.use(
  53. (response) =&gt; response,
  54. async (error) =&gt; {
  55. const prevRequest = error?.config;
  56. if (error?.response.status === 403 &amp;&amp; !prevRequest?.sent) {
  57. prevRequest.send = true;
  58. const newToken = await refresh();
  59. const accessToken = newToken.accessToken;
  60. prevRequest.headers[&quot;Authorization&quot;] = `Bearer ${accessToken}`;
  61. return axiosPrivate(prevRequest);
  62. }
  63. return Promise.reject(error);
  64. }
  65. );
  66. setIsSet(true)
  67. return () =&gt; {
  68. axiosPrivate.interceptors.request.eject(requestIntercept);
  69. axiosPrivate.interceptors.response.eject(responseIntercept);
  70. };
  71. }, [user, refresh]);
  72. return isSet &amp;&amp; children;
  73. };
  74. But typescript won&#39;t allow me to do that.

How this issue can be solved?

答案1

得分: 1

虽然这没有解决我的主要问题,但我发现绕过这个 TypeScript 错误相当容易:

  1. return <>{isSet && children}</>;
英文:

Although this did not fix my main issue, but I figured out that it's quite easy to bypass this typescript error:

  1. return &lt;&gt;{isSet &amp;&amp; children}&lt;/&gt;

huangapple
  • 本文由 发表于 2023年1月9日 00:06:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049294.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定