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

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

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

问题

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

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

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

const [isSet, setIsSet] = useState<boolean>(false);

// ...

setIsSet(true)

// ...

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.

const AxiosPrivateInterceptor: FC&lt;IProps&gt; = ({ children }) =&gt; {
	const { user } = useAppSelector(selectAuthUser);
	const refresh = useRefreshToken();

	useEffect(() =&gt; {
		const requestIntercept = axiosPrivate.interceptors.request.use(
			(config: AxiosRequestConfig) =&gt; {
				config.headers = config.headers ?? {};
				if (!config?.headers[&quot;Authorization&quot;]) {
					config.headers[&quot;Authorization&quot;] = `Bearer ${user?.accessToken}`;
				}
				return config;
			},
			(error) =&gt; Promise.reject(error)
		);

		const responseIntercept = axiosPrivate.interceptors.response.use(
			(response) =&gt; response,
			async (error) =&gt; {
				const prevRequest = error?.config;
				if (error?.response.status === 403 &amp;&amp; !prevRequest?.sent) {
					prevRequest.send = true;
					const newToken = await refresh();
					const accessToken = newToken.accessToken;
					prevRequest.headers[&quot;Authorization&quot;] = `Bearer ${accessToken}`;
					return axiosPrivate(prevRequest);
				}
				return Promise.reject(error);
			}
		);

		return () =&gt; {
			axiosPrivate.interceptors.request.eject(requestIntercept);
			axiosPrivate.interceptors.response.eject(responseIntercept);
		};
	}, [user, refresh]);

	return children;
};


I also tried to add a state like this :

const AxiosPrivateInterceptor: FC&lt;IProps&gt; = ({ children }) =&gt; {
	const { user } = useAppSelector(selectAuthUser);
	const refresh = useRefreshToken();
	const [isSet, setIsSet] = useState&lt;boolean&gt;(false);

	useEffect(() =&gt; {
		const requestIntercept = axiosPrivate.interceptors.request.use(
			(config: AxiosRequestConfig) =&gt; {
				config.headers = config.headers ?? {};
				if (!config?.headers[&quot;Authorization&quot;]) {
					config.headers[&quot;Authorization&quot;] = `Bearer ${user?.accessToken}`;
				}
				return config;
			},
			(error) =&gt; Promise.reject(error)
		);

		const responseIntercept = axiosPrivate.interceptors.response.use(
			(response) =&gt; response,
			async (error) =&gt; {
				const prevRequest = error?.config;
				if (error?.response.status === 403 &amp;&amp; !prevRequest?.sent) {
					prevRequest.send = true;
					const newToken = await refresh();
					const accessToken = newToken.accessToken;
					prevRequest.headers[&quot;Authorization&quot;] = `Bearer ${accessToken}`;
					return axiosPrivate(prevRequest);
				}
				return Promise.reject(error);
			}
		);
setIsSet(true)

		return () =&gt; {
			axiosPrivate.interceptors.request.eject(requestIntercept);
			axiosPrivate.interceptors.response.eject(responseIntercept);
		};
	}, [user, refresh]);

	return isSet &amp;&amp; children;
};

But typescript won&#39;t allow me to do that. 

How this issue can be solved?

答案1

得分: 1

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

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:

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:

确定