Я хочу добавить пользовательскую карту на одну из моих страниц, которая должна вызывать остальные 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.info(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>
);
и, конечно же, у меня есть мой ресурс App.js для вызова API «кликов»:
мой App.js:
<Resource name = "clicks" options = {{ label: 'Legutóbbi kattintások' }} list = {ClickList} />
Что я делаю не так, что мой datapovider не вызывает мой API?
мой поставщик данных /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)
);
};
};
Ответ: undef... и, как я уже сказал, API ничего не передает... Где react-admin извлекает данные с помощью данного вызова dataProvider? Насколько я понимаю, dataProviderFactory просто создает объект, но не извлекает его. Как это работает в реакции?





Сначала вам нужно инициализировать свое состояние
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 }))
}
);
}
Я сделал это, фиксированное состояние, но я все еще получаю undef для dailyclick. Я должен вернуть JSON с 1 элементом из API, что-то вроде этого: {count: 0}, поэтому я просто установил this.setState({ dailyclick: response.data.count }) - на этот раз я получил undef: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Также я не вижу в логах входящий вызов API на стороне API.
Я мог бы исправить это в то же время. Было несколько мелких проблем:
Итак, вы тщательно его отладили, добавили console.info() в разные места вызова dataProviderFactory из вашего компонента, что-нибудь появилось, что могло бы помочь? В первом .then() как выглядит «ответ»?