英文:
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<IProps> = ({ children }) => {
	const { user } = useAppSelector(selectAuthUser);
	const refresh = useRefreshToken();
	useEffect(() => {
		const requestIntercept = axiosPrivate.interceptors.request.use(
			(config: AxiosRequestConfig) => {
				config.headers = config.headers ?? {};
				if (!config?.headers["Authorization"]) {
					config.headers["Authorization"] = `Bearer ${user?.accessToken}`;
				}
				return config;
			},
			(error) => Promise.reject(error)
		);
		const responseIntercept = axiosPrivate.interceptors.response.use(
			(response) => response,
			async (error) => {
				const prevRequest = error?.config;
				if (error?.response.status === 403 && !prevRequest?.sent) {
					prevRequest.send = true;
					const newToken = await refresh();
					const accessToken = newToken.accessToken;
					prevRequest.headers["Authorization"] = `Bearer ${accessToken}`;
					return axiosPrivate(prevRequest);
				}
				return Promise.reject(error);
			}
		);
		return () => {
			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<IProps> = ({ children }) => {
	const { user } = useAppSelector(selectAuthUser);
	const refresh = useRefreshToken();
	const [isSet, setIsSet] = useState<boolean>(false);
	useEffect(() => {
		const requestIntercept = axiosPrivate.interceptors.request.use(
			(config: AxiosRequestConfig) => {
				config.headers = config.headers ?? {};
				if (!config?.headers["Authorization"]) {
					config.headers["Authorization"] = `Bearer ${user?.accessToken}`;
				}
				return config;
			},
			(error) => Promise.reject(error)
		);
		const responseIntercept = axiosPrivate.interceptors.response.use(
			(response) => response,
			async (error) => {
				const prevRequest = error?.config;
				if (error?.response.status === 403 && !prevRequest?.sent) {
					prevRequest.send = true;
					const newToken = await refresh();
					const accessToken = newToken.accessToken;
					prevRequest.headers["Authorization"] = `Bearer ${accessToken}`;
					return axiosPrivate(prevRequest);
				}
				return Promise.reject(error);
			}
		);
setIsSet(true)
		return () => {
			axiosPrivate.interceptors.request.eject(requestIntercept);
			axiosPrivate.interceptors.response.eject(responseIntercept);
		};
	}, [user, refresh]);
	return isSet && children;
};
But typescript won'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 <>{isSet && children}</>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论