React-admin组件不使用dataprovider来调用api

时间:2019-02-28 14:54:49

标签: reactjs react-admin

我想在页面之一上添加自定义卡片,该卡片应使用过滤器调用其余的api。

我为此编写了一个新组件,但返回错误,但未定义该响应。我检查了一下,没有调用到达我的api,因此我很确定未定义响应,因为api调用没有发生,没有执行。

这是我组件的代码:

import React, { Component } from 'react';
import { GET_LIST } from 'react-admin';
import dataProviderFactory from '../dataprovider/rest';

import StatsCard from './from_director/StatsCard';


class ClickStats extends Component {
    state = {};

componentDidMount() {
    dataProviderFactory(process.env.REACT_APP_DATA_PROVIDER).then(
        dataProvider => {
            dataProvider(GET_LIST, 'clicks', {
                filter: {
                    interval: 'day',
                    site_id: '1',
                    count: '1'
                },
            })
                .then(response => response.data)
                .then( dailyclick =>
                    this.setState({ dailyclick: response.data }),
                    console.log(response.data)
                )
        }
    );
}

render() {
    const {
        dailyclick,
    } = this.state;
    return (
                <StatsCard
                  statValue={dailyclick}
                  statLabel={'Napi Katt'}
                  icon={<i className="fa fa-check-square-o"></i>}
                  backColor={'red'}
                />
    );
}
}
export default ClickStats; 

我想像这样在我的列表中使用它:

import ClickStats from '../field/ClickStats';

export const ClickList = props => (
    <List {...props} bulkActions={false} filters={<ClickFilterList />} pagination={<ClickPagination />} perPage={20000}>
        <ClickStats />
        <Datagrid rowClick="edit">
            <ReferenceField label="Hirdeto" source="ad" reference="ads" linkType={false}><NumberField label="Hirdeto" source="users.name" /></ReferenceField>
            <ReferenceField label="Hirdetes" source="ad" reference="ads"><NumberField label="Hirdetes" source="title" /></ReferenceField>
            <IpConverter source="ip" />
            <TextField source="time" />
        </Datagrid>
    </List>
);

当然,我有适用于“点击” api调用的App.js资源:

我的App.js:

<Resource name="clicks" options={{ label: 'Legutóbbi kattintások' }} list={ClickList} />

我的datapovider没有调用我的api,我该怎么办?

我的dataprovider / rest.js

import { stringify } from 'query-string';
import {
  fetchUtils,
  GET_LIST,
  GET_ONE,
  GET_MANY,
  GET_MANY_REFERENCE,
  CREATE,
  UPDATE,
  UPDATE_MANY,
  DELETE,
  DELETE_MANY,
} from 'react-admin';

export default (apiUrl, httpClient = fetchUtils.fetchJson) => {
const convertDataRequestToHTTP = (type, resource, params) => {
    let url = '';
    const options = {};
    switch (type) {
        case GET_LIST: {
            const { page, perPage } = params.pagination;
            const { field, order } = params.sort;
            const query = {
                ...fetchUtils.flattenObject(params.filter),
                sort: field,
                order: order,
                start: (page - 1) * perPage,
                end: page * perPage,
            };
                url = `${apiUrl}/${resource}?${stringify(query)}`;
            break;
        }
        case GET_ONE:
            url = `${apiUrl}/${resource}/${params.id}`;
            break;
        case GET_MANY_REFERENCE: {
            const { page, perPage } = params.pagination;
            const { field, order } = params.sort;
            const query = {
                ...fetchUtils.flattenObject(params.filter),
                [params.target]: params.id,
                _sort: field,
                _order: order,
                _start: (page - 1) * perPage,
                _end: page * perPage,
            };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            break;
        }
        case UPDATE:
            url = `${apiUrl}/${resource}/${params.id}`;
            options.method = 'POST';
            options.body = JSON.stringify(params.data);
            break;
        case CREATE:
            url = `${apiUrl}/${resource}`;
            options.method = 'PUT';
            options.body = JSON.stringify(params.data);
            break;
        case DELETE:
            url = `${apiUrl}/${resource}/${params.id}`;
            options.method = 'DELETE';
            break;
        case GET_MANY: {
            url = `${apiUrl}/${resource}`;
            break;
        }
        default:
            throw new Error(`Unsupported fetch action type ${type}`);
    }
    return { url, options };
};

const convertHTTPResponse = (response, type, resource, params) => {
    const { headers, json } = response;
    switch (type) {
        case GET_LIST:
        case GET_MANY_REFERENCE:
            if (!headers.has('x-total-count')) {
                throw new Error(
                    'The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?'
                );
            }
            return {
                data: json,
                total: parseInt(
                    headers
                        .get('x-total-count')
                        .split('/')
                        .pop(),
                    10
                ),
            };
        case CREATE:
            return { data: { ...params.data, id: json.id } };
        default:
            return { data: json };
    }
};

return (type, resource, params) => {
    // json-server doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
    if (type === UPDATE_MANY) {
        return Promise.all(
            params.ids.map(id =>
                httpClient(`${apiUrl}/${resource}/${id}`, {
                    method: 'PUT',
                    body: JSON.stringify(params.data),
                })
            )
        ).then(responses => ({
            data: responses.map(response => response.json),
        }));
    }
    // json-server doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
    if (type === DELETE_MANY) {
        return Promise.all(
            params.ids.map(id =>
                httpClient(`${apiUrl}/${resource}/${id}`, {
                    method: 'DELETE',
                })
            )
        ).then(responses => ({
            data: responses.map(response => response.json),
        }));
    }
    const { url, options } = convertDataRequestToHTTP(
        type,
        resource,
        params
    );
    return httpClient(url, options).then(response =>
        convertHTTPResponse(response, type, resource, params)
    );
};
};

2 个答案:

答案 0 :(得分:1)

同时我可以修复它。有多个小问题:

  • 在列表视图中,我的ClickStats无法正常工作
    • DevTools清楚显示了
  • 我不得不将dataprovider从ra-data-json-server更改为ra-data-simple-rest,突然一切都正常了

答案 1 :(得分:0)

首先,您需要初始化状态

state = {
dailyclick : {}
};

然后

componentDidMount() {
    dataProviderFactory(process.env.REACT_APP_DATA_PROVIDER).then(
        dataProvider => {
            dataProvider(GET_LIST, 'clicks', {
                filter: {
                    interval: 'day',
                    site_id: '1',
                    count: '1'
                },
            })
                .then(response => this.setState({ dailyclick: response.data }))
        }
    );
}