suddjian commented on a change in pull request #13761:
URL: https://github.com/apache/superset/pull/13761#discussion_r600131432
##########
File path: superset-frontend/src/common/hooks/apiResources/apiResources.ts
##########
@@ -67,6 +72,163 @@ const initialState: LoadingState = {
error: null,
};
+const RESOURCE_START = 'RESOURCE_START';
+const RESOURCE_SUCCESS = 'RESOURCE_SUCCESS';
+const RESOURCE_ERROR = 'RESOURCE_FETCH_ERROR';
+
+type FetchStart = {
+ type: typeof RESOURCE_START;
+ clientId: string;
+};
+
+type FetchSuccess<T = any> = {
+ type: typeof RESOURCE_SUCCESS;
+ clientId: string;
+ result: T;
+};
+
+type FetchError = {
+ type: typeof RESOURCE_ERROR;
+ clientId: string;
+ error: Error;
+};
+
+type ResourceAction = FetchStart | FetchSuccess | FetchError;
+
+export function resourcesReducer(
+ state: ResourcesState = initialResourcesState,
+ action: ResourceAction,
+): ResourcesState {
+ switch (action.type) {
+ case RESOURCE_START: {
+ return {
+ ...state,
+ [action.clientId]: {
+ status: ResourceStatus.LOADING,
+ result: null,
+ error: null,
+ },
+ };
+ }
+ case RESOURCE_SUCCESS: {
+ const { clientId, result } = action;
+ return {
+ ...state,
+ [clientId]: {
+ status: ResourceStatus.COMPLETE,
+ result,
+ error: null,
+ },
+ };
+ }
+ case RESOURCE_ERROR: {
+ const { clientId, error } = action as FetchError;
+ return {
+ ...state,
+ [clientId]: {
+ status: ResourceStatus.ERROR,
+ result: null,
+ error,
+ },
+ };
+ }
+ default:
+ return state;
+ }
+}
+
+type ReduxRootState = { apiResources: ResourcesState };
+const selectResource = <RESULT>(clientId: string) => (
+ state: ReduxRootState,
+): Resource<RESULT> | null => state.apiResources[clientId] ?? null;
+
+async function fetchData<RESULT>(
+ dispatch: Dispatch<ResourceAction>,
+ endpoint: string,
+) {
+ const clientId = uuidv1();
+
+ dispatch({
+ type: RESOURCE_START,
+ clientId,
+ });
+
+ const fetchResource = makeApi<{}, RESULT>({
+ method: 'GET',
+ endpoint,
+ });
+
+ try {
+ const result = await fetchResource({});
+ dispatch({
+ type: RESOURCE_SUCCESS,
+ clientId,
+ result,
+ });
+ } catch (error) {
+ dispatch({
+ type: RESOURCE_ERROR,
+ clientId,
+ error,
+ });
+ }
+}
+
+export function useApiFetch<RESULT>(endpoint: string): void {
+ const dispatch = useDispatch<Dispatch<ResourceAction>>();
+ const resource = useSelector(selectResource(endpoint));
+
+ useEffect(() => {
+ if (resource != null) {
+ // fetching already underway/complete, don't duplicate work.
+ return;
+ }
+
+ fetchData<RESULT>(dispatch, endpoint);
+ }, [endpoint, resource, dispatch]);
Review comment:
If `endpoint` were to change, request cancellation might be required to
prevent race conditions.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]