import { Component, ReactNode } from 'react'; import isEqual from 'lodash/isEqual'; import withDataProvider from './withDataProvider'; type DataProviderCallback = ( type: string, resource: string, payload?: any, options?: any ) => Promise; interface ChildrenFuncParams { data?: any; total?: number; loading: boolean; error?: any; } interface RawProps { children: (params: ChildrenFuncParams) => ReactNode; type: string; resource: string; payload?: any; options?: any; } interface Props extends RawProps { dataProvider: DataProviderCallback; } interface State { data?: any; total?: number; loading: boolean; error?: any; } /** * Fetch the data provider and pass the result to a child function * * @example * * const UserProfile = ({ record }) => ( * * {({ data, loading, error }) => { * if (loading) { return ; } * if (error) { return

ERROR

; } * return
User {data.username}
; * }} *
* ); * * @example * * const payload = { * pagination: { page: 1, perPage: 10 }, * sort: { field: 'username', order: 'ASC' }, * }; * const UserList = () => ( * * {({ data, total, loading, error }) => { * if (loading) { return ; } * if (error) { return

ERROR

; } * return ( *
*

Total users: {total}

*
    * {data.map(user =>
  • {user.username}
  • )} *
*
* ); * }} *
* ); */ class Query extends Component { state = { data: null, total: null, loading: true, error: null, }; callDataProvider = () => { const { dataProvider, type, resource, payload, options } = this.props; dataProvider(type, resource, payload, options) .then(({ data, total }) => { this.setState({ data, total, loading: false, }); }) .catch(error => { this.setState({ error, loading: false, }); }); }; componentDidMount = () => { this.callDataProvider(); }; componentDidUpdate = prevProps => { if ( prevProps.type !== this.props.type || prevProps.resource !== this.props.resource || !isEqual(prevProps.payload, this.props.payload) || !isEqual(prevProps.options, this.props.options) ) { this.callDataProvider(); } }; render() { const { children } = this.props; return children(this.state); } } export default withDataProvider(Query);