如何在 promise.all 解决时过滤两种不同状态的数据?
How to filter data in two different state when promise.all resolved?
我发送了两个请求来获取
1- 我的服务
2- 管理服务
当我收到响应时,我将状态设置为“myService,admin”。
现在包含我的服务的管理服务。
所以我想过滤我在管理服务中的服务是否从数组中删除管理服务。
所以我正在尝试使用 new Set
但不起作用,也许我错过了什么
另一个问题是我使用 Promise.all
来等待这两个请求,但是当我在那里记录状态时,我得到了初始状态 'empty'
数据样本“我的服务和管理员”
[
//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}
/>
我认为您使用 promises.all
有误。
理想情况下 promises.all
仅当您承诺的所有功能 return 都可以等待时才能等待,但在您的情况下,您正在 returning 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
}, []);
首先你应该return getMyServices
和 getAdminServices
的承诺。
此外,在 React 中设置状态是异步的。因此 myServices
和 adminServices
的更新不能保证在您尝试使用它们时反映出来。我建议你 return 承诺的结果并使用这些值而不是状态。
示例:
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- 我的服务 2- 管理服务
当我收到响应时,我将状态设置为“myService,admin”。
现在包含我的服务的管理服务。 所以我想过滤我在管理服务中的服务是否从数组中删除管理服务。
所以我正在尝试使用 new Set
但不起作用,也许我错过了什么
另一个问题是我使用 Promise.all
来等待这两个请求,但是当我在那里记录状态时,我得到了初始状态 'empty'
数据样本“我的服务和管理员”
[
//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}
/>
我认为您使用 promises.all
有误。
理想情况下 promises.all
仅当您承诺的所有功能 return 都可以等待时才能等待,但在您的情况下,您正在 returning 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
}, []);
首先你应该return getMyServices
和 getAdminServices
的承诺。
此外,在 React 中设置状态是异步的。因此 myServices
和 adminServices
的更新不能保证在您尝试使用它们时反映出来。我建议你 return 承诺的结果并使用这些值而不是状态。
示例:
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
}, []);