Skip to content

Instantly share code, notes, and snippets.

@rikuba
Created January 25, 2018 18:04
Show Gist options
  • Save rikuba/0ab27c339cdf795584932434bdc4a670 to your computer and use it in GitHub Desktop.
Save rikuba/0ab27c339cdf795584932434bdc4a670 to your computer and use it in GitHub Desktop.
Define thunk actions as classes in TypeScript (It's nonsense...)
import { ThunkAction } from "redux-thunk";
import { RequestPosts, ReceivePosts } from './creators';
import { State } from "../reducers/index";
const ThunkActionClass = class {
constructor(thunk: any) {
return thunk;
}
} as {
new<R, S, A>(thunk: ThunkAction<R, S, A>): ThunkAction<R, S, A>;
};
export class FetchPosts extends ThunkActionClass<Promise<void>, State, undefined> {
constructor(subreddit: string) {
super(async (dispatch, getState) => {
dispatch(new RequestPosts({ subreddit }));
try {
const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
const json = await response.json();
dispatch(new ReceivePosts(subreddit, json));
} catch (e) {
dispatch(new ReceivePosts(subreddit, { data: { children: [] } }));
}
});
}
}
const shouldFetchPosts = (state: State, subreddit: string) => {
const posts = state.postsBySubreddit[subreddit];
if (!posts) {
return true;
}
if (posts.isFetching) {
return false;
}
return posts.didInvalidate;
};
export class FetchPostsIfNeeded extends ThunkActionClass<Promise<void>, any, undefined> {
constructor(subreddit: string) {
super(async (dispatch, getState) => {
if (shouldFetchPosts(getState(), subreddit)) {
await dispatch(new FetchPosts(subreddit));
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment