Guest User

Untitled

a guest
Apr 21st, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.62 KB | None | 0 0
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3.  
  4. class DataFetcher extends Component {
  5. constructor(props) {
  6. super(props);
  7.  
  8. this._activePromises = 0;
  9. this.result = {};
  10. this.errors = null;
  11. this._toBeExecuted = Object.keys(props.loader).length;
  12. this.checkState = this.checkState.bind(this);
  13. this.spawn = this.spawn.bind(this);
  14.  
  15. this.state = {
  16. loading: true,
  17. };
  18. }
  19. checkState() {
  20. if (this._activePromises === 0 && this._toBeExecuted === 0) {
  21. this.setState({
  22. loading: false,
  23. result: { ...this.result },
  24. errors: this.errors || null,
  25. });
  26. }
  27. }
  28. spawn(name, fetcher) {
  29. this._activePromises++;
  30. this._toBeExecuted--;
  31. fetcher()
  32. .then(data => {
  33. this.result[name] = data;
  34. this._activePromises--;
  35. })
  36. .catch(error => {
  37. if (!this.errors) this.errors = {};
  38. this.errors[name] = error;
  39. this._activePromises--;
  40. })
  41. .then(() => {
  42. this.checkState();
  43. });
  44. }
  45. componentDidMount() {
  46. const { loader } = this.props;
  47. Object.keys(loader).map(x => {
  48. this.spawn(x, loader[x]);
  49. });
  50. }
  51. render() {
  52. const { result, loading, errors } = this.state;
  53. const { render, children } = this.props;
  54. if (typeof render === 'function') {
  55. return render({ result, loading, errors });
  56. }
  57. if (typeof children === 'function') {
  58. return children({ result, loading, errors });
  59. }
  60. }
  61. }
  62.  
  63. DataFetcher.propTypes = {
  64. loader: PropTypes.object.isRequired,
  65. render: PropTypes.func,
  66. children: PropTypes.func,
  67. };
  68.  
  69. export default DataFetcher;
Add Comment
Please, Sign In to add comment