Guest User

Untitled

a guest
Mar 22nd, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.49 KB | None | 0 0
  1. import { action, observable } from "mobx"
  2. import { observer } from "mobx-react"
  3. import * as React from "react"
  4.  
  5. export type FetcherProps<T> = {
  6. longWaitTimeout?: number
  7. fetch: () => Promise<T>
  8. render: (fetchState: FetchState<T>) => React.ReactNode
  9. }
  10.  
  11. export type FetchState<T> =
  12. // component hasn't mounted yet, nothing is happening
  13. | { state: "idle" }
  14.  
  15. // currently fetching the data
  16. | { state: "fetching" }
  17.  
  18. // fetching the data, though it's taken a while
  19. | { state: "fetching-long" }
  20.  
  21. // received data
  22. | { state: "success"; data: T }
  23.  
  24. // error fetching data
  25. | { state: "error"; error: any }
  26.  
  27. @observer
  28. export class Fetcher<T> extends React.Component<FetcherProps<T>> {
  29. @observable fetchState: FetchState<T> = { state: "idle" }
  30.  
  31. @action
  32. setFetchState(fetchState: FetchState<T>) {
  33. this.fetchState = fetchState
  34. }
  35.  
  36. async doFetch() {
  37. this.setFetchState({ state: "fetching" })
  38.  
  39. setTimeout(() => {
  40. if (this.fetchState.state === "fetching") {
  41. this.setFetchState({ state: "fetching-long" })
  42. }
  43. }, this.props.longWaitTimeout || 2500)
  44.  
  45. try {
  46. const data = await this.props.fetch()
  47. this.setFetchState({ state: "success", data })
  48. } catch (error) {
  49. this.setFetchState({ state: "error", error })
  50. }
  51. }
  52.  
  53. componentDidMount() {
  54. // tslint:disable-next-line
  55. this.doFetch()
  56. }
  57. render() {
  58. return this.props.render(this.fetchState)
  59. }
  60. }
  61.  
  62. export function createFetcher<T>() {
  63. return Fetcher as new () => Fetcher<T>
  64. }
Add Comment
Please, Sign In to add comment