Source

components/update-on-interval.js

  1. import { any, func, number } from 'prop-types';
  2. import React from 'react';
  3. /**
  4. * This render props component willupdate it's children via props while executing data loaders sent as props to the component.
  5. *
  6. * Note: Dataloaders are made to be at an app level to keep the component generic, the return of Dataloaders are sent as props to its children.
  7. *
  8. * Example
  9. * ```javascript
  10. * import {UpdateOnInterval} from '@quintype/components';
  11. *
  12. * const story = {
  13. * 'example' : 'data'
  14. * };
  15. *
  16. * function getData() {
  17. * return fetch('/url/something')//...
  18. * }
  19. *
  20. * <UpdateOnInterval dataLoader={getData} interval={3000} initData={story}>
  21. * {
  22. * ({data}) => <Component data={data}></Component>
  23. * }
  24. * </UpdateOnInterval>
  25. * ```
  26. * @component
  27. * @hideconstructor
  28. * @category Other
  29. */
  30. export class UpdateOnInterval extends React.Component {
  31. constructor(props){
  32. super(props);
  33. this.fetchIntervalIndex = -1;
  34. this.state = {
  35. data: this.props.initData,
  36. };
  37. }
  38. componentDidMount() {
  39. this.registerInterval();
  40. }
  41. componentWillMount() {
  42. this.unregisterInterval();
  43. }
  44. registerInterval() {
  45. this.fetchIntervalIndex = setInterval(() => this.setData(), this.props.interval);
  46. }
  47. unregisterInterval() {
  48. clearInterval(this.fetchIntervalIndex);
  49. }
  50. async setData() {
  51. const data = typeof this.props.dataLoader === 'function' ? await this.props.dataLoader() : {};
  52. this.setState({data});
  53. }
  54. render() {
  55. const {children} = this.props;
  56. const {data} = this.state;
  57. return children({data});
  58. }
  59. }
  60. UpdateOnInterval.defaultProps = {
  61. interval : 30000,
  62. initData: {}
  63. };
  64. UpdateOnInterval.propTypes = {
  65. /** Sets the time (ms) */
  66. interval: number,
  67. /** Async Function to load data */
  68. dataLoader: func.isRequired,
  69. /** The initial data for server side rendering */
  70. initData: any.isRequired
  71. };