#javascript #reactjs #react-native #promise #es6-promise
#javascript #reactjs #react-native #обещание #es6-обещание
Вопрос:
Я отправляю два запроса, чтобы получить
1- мои службы 2- службы администратора
когда я получил ответ, я установил состояние «MyService, admin».
теперь администрируйте сервисы, содержащие мои сервисы. Итак, я хочу отфильтровать, удаляют ли мои службы в службе администратора службу администратора из массива.
итак, я пытаюсь использовать new Set
, но не работает, может быть, я что-то пропустил
и еще одна проблема, которую я использую Promise.all
для ожидания двух запросов, но когда я регистрирую там состояние, я получаю начальное состояние «пустое»
образец данных «мои службы и администратор»
[
//my service
{
"id": 1,
"img": ".....",
"name": "service 1"
},
{
"id": 2,
"img": ".....",
"name": "service 2"
},
{
"id": 3,
"img": ".....",
"name": "service 3"
},
//admin service
{
"id": 1,
"img": ".....",
"name": "service 1"
},
]
Фрагмент кода
const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
Api.post('/admin/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
setAdminServices(serviceModified);
})
.catch((err) => console.log('err', err));
};
const getMyServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
Api.post('/vendor/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
setMyServices(serviceModified);
setSelectedService(serviceModified); // for checkbox
})
.catch((err) => console.log('err', err));
};
Promise.all([getMyServices(), getAdminServices()]).then(() => {
let allServices = [...myServices, ...adminServices]; // log empty!
let uniq = [...new Set(allServices)];
console.log(myServices);
console.log('filtered', uniq);
console.log('here i want to filter the data', allServices);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
UI
<FlatList
data={allService}
keyExtractor={(item, index) => String(index)}
renderItem={renderMyServices}
/>
Комментарии:
1. Объявите
let serviceModified = [];
иlet serviceModified = [];
перед этой строкойconst getAdminServices = async () => {
, это может вам помочь2. @EhsanNazeri к сожалению, нет! он по-прежнему возвращает пустой
Ответ №1:
Прежде всего, вы должны вернуть обещания из getMyServices
и getAdminServices
.
Кроме того, настройка состояния в react является асинхронной. Таким образом, обновления myServices
и adminServices
не гарантированно будут отражены к моменту, когда вы попытаетесь их использовать. Я предлагаю вам вернуть результаты из обещаний и использовать эти значения вместо состояния.
Пример:
const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/admin/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
return serviceModified;
})
.catch((err) => console.log('err', err));
};
const getMyServices = () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/vendor/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
return serviceModified;
})
.catch((err) => console.log('err', err));
};
Promise.all([getMyServices(), getAdminServices()]).then(([myServices, adminServices]) => {
// set state and do stuff
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Комментарии:
1. Потрясающе! это данные журнала очень хорошо, но о моих вещах:»D, как я уже говорил,
Set
работает не так, как ожидалось, можете ли вы, пожалуйста, проверить это?2. Эй, еще раз, когда
return Api.post(...)
это означает, что здесь возвращается обещание? и когда возвращаютserviceModified
данные для.then
ввода? и зачем тогда получать данные в массиве([myServices, adminServices])
3. Да, он возвращает обещание. Да, когда вы возвращаете
serviceModified
это дляthen
. Это массив, потому что Promise.all проходит через массив. Разрушение массива
Ответ №2:
Я думаю, вы используете promises.all
неправильно.
В идеале promises.all
может ожидать, только если все функции возвращают вам обещания, но в вашем случае вы возвращаетесь undefined
.
Следовательно, даже до ответа на вызов API Promises.all
завершит выполнение и then
также будет выполнен.
вы можете реструктурировать свой код примерно так, как показано ниже (тем не менее, я вижу много возможностей для рефакторинга).
const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/admin/service', {}, {headers});
};
const setMyServices = (res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
setMyServices(serviceModified);
setSelectedService(serviceModified); // for checkbox
return serviceModified;
}
const setAdminServices = (res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
setAdminServices(serviceModified);
return serviceModified;
}
const getMyServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/vendor/service', {}, {headers});
};
Promise.all([getMyServices(), getAdminServices()]).then((data) => {
console.log(data); // will have [myServiceResponse, adminServiceReponse];
const myServices = setMyServices(data[0]);
const adminServices = setAdminServices(data[1]);
let allServices = [...myServices, ...adminServices]; // log empty!
// set doesn't work this way, use `uniq` utility function from `lodash` or develop a custom one if required.
let uniq = [...new Set(allServices)];
console.log(myServices);
console.log('filtered', uniq);
console.log('here i want to filter the data', allServices);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Комментарии:
1. Спасибо за ответ, но @L Lawliet Ответьте, что это немного просто / мини 🙂