Redux 如何从数组对象中的超链接中获取数据并返回结果?
我的后端返回以下数据。对于某些数据,我需要获取一个超链接以获取数据。而这是一个简单的物体。我很难从一系列对象中获取数据Redux 如何从数组对象中的超链接中获取数据并返回结果?,redux,async-await,redux-toolkit,Redux,Async Await,Redux Toolkit,我的后端返回以下数据。对于某些数据,我需要获取一个超链接以获取数据。而这是一个简单的物体。我很难从一系列对象中获取数据 { count: 2, next: null, previous: null, results: [ { id: 3, title: 'Story-2', description: 'Law window student scientist betwee
{
count: 2,
next: null,
previous: null,
results: [
{
id: 3,
title: 'Story-2',
description: 'Law window student scientist between news receive. Sign require point.',
price: '0.00',
author: '23f1a20asdfsa9-8175-4aasdfdsaf54-9a42-27fesadfdsaff258fc86',
place: 3,
placeUrl: 'http://localhost:8000/api/v1/places/3/',
imagesUrl: 'http://localhost:8000/api/v1/story-images/?place=3',
titleImage: 'http://localhost:8000/media/story_media/example_jJiJGMr.jpg'
},
{
id: 4,
title: 'Test',
description: 'sdfdsdsfdsf',
price: '0.08',
author: '23f1a209-817sdfdsf5-4a54-9a42-27fef25sadfds8fc86',
place: 1,
placeUrl: 'http://localhost:8000/api/v1/places/1/',
imagesUrl: 'http://localhost:8000/api/v1/story-images/?place=4',
titleImage: 'http://localhost:8000/api/v1/stories/?limit=9&offset=0&author=23f1a209-8175-4a54-9a42-27fef258fc86'
}
]
}
我现在想访问PlaceUrl的数据(例如,包含名称、城市等),并将数据添加到oiginal对象。我目前的做法是这样的。但感觉不对:
const selectStoriesList = (state) => state.story.storyList.results;
export const selectStoriesListView = createSelector(
selectStoriesList,
(selectStoriesList) => {
let preparedStories = [];
if (selectStoriesList && selectStoriesList.length > 0) {
const promises = selectStoriesList.map(async (item) => {
const place = await axios.get(item.placeUrl, tokenConfig());
return {
authorUsername: item.author,
authorNickname: "",
authorImage: "",
titleImage: item.titleImage,
title: item.title,
place: place.data.name,
city: place.data.city,
linkToProfile: "",
linkToPlace: "",
linkToStory: `www.ssdfsuy`,
storyPrice: item.price,
storyIsBought: "",
};
});
console.log(promises);
let preparedStories = Promise.all(promises).then((values) => {
console.log(values);
return values;
});
return Promise.all(promises);
// return Promise.all(promises);
} else {
return preparedStories;
}
}
);
fetch调用应该是什么样子?欢迎任何提示。选择器不是执行异步获取的地方。它应该是从您的存储中简单地选择数据 这里要处理的是两种实体类型之间的关系:
故事
和地点
。您可能希望使用将数据存储在存储中,以便您可以通过其id查找位置
您可以通过多种方式触发位置提取:
组件中的
选择故事时只返回地点id。您的故事组件将呈现一个位置组件,如
。该Place
组件将从存储中选择Place对象,并使用useffect
钩住dispatch
对其id执行“请求放置”操作
在砰的一声中
用于获取故事的操作可以通过payload creator函数的调用分派
其他操作。或者,它可以执行多个API请求,并在包含地点和故事的单个操作中返回数据
下面是最后一个想法的代码,尽管我实际上更喜欢基于组件的方法
import {
configureStore,
createAsyncThunk,
createEntityAdapter,
createReducer,
createSelector
} from "@reduxjs/toolkit";
import axios from "axios";
import { uniq } from "lodash";
const tokenConfig = () => ({});
const placesAdapter = createEntityAdapter();
const storiesAdapter = createEntityAdapter();
export const placeSelectors = placesAdapter.getSelectors(
(state) => state.place
);
export const storySelectors = storiesAdapter.getSelectors(
(state) => state.story
);
const fetchStories = createAsyncThunk(
"fetchStories",
async (_, { getState }) => {
// fetch the stories
const storyRes = await axios.get("/api/v1/stories/", tokenConfig());
const storyData = storyRes.data;
// array of place ids for each story
const placeIds = storyData.results.map((story) => story.place);
// find which place ids are already in the state and can be skipped over
const loadedPlaceIds = placeSelectors.selectIds(getState());
// filter out duplicates and already loaded
const idsToFetch = uniq(
placeIds.filter((id) => !loadedPlaceIds.includes(id))
);
// fetch all places
const places = await Promise.all(
idsToFetch.map((id) => axios.get(`/api/v1/places/${id}/`, tokenConfig()))
);
// return your data
return {
places, // an array of place objects
storyData // the story data
};
}
);
export const storiesReducer = createReducer(
storiesAdapter.getInitialState({
storyList: {
count: 0,
next: null,
previous: null,
ids: []
}
}),
(builder) =>
builder.addCase(fetchStories.fulfilled, (state, action) => {
const data = action.payload.storyData;
// save all of the stories
storiesAdapter.upsertMany(state, data.results);
// save the list, but with just the ids for the stories
state.storyList = {
...data,
ids: data.results.map((story) => story.id)
};
})
);
export const placesReducer = createReducer(
placesAdapter.getInitialState(),
(builder) =>
builder.addCase(fetchStories.fulfilled, (state, action) => {
// save all of the places
placesAdapter.upsertMany(state, action.payload.places);
})
);
export const selectStoriesListView = createSelector(
// select the list of story ids
(state) => state.story.storyList.results,
// select the stories
(state) => state.story.entities,
// select the places
(state) => state.place.entities,
// combine all
(ids, stories, places) => {
// map ids to objects
const storyObjects = ids.map((id) => stories[id]);
// reformat
return storyObjects.map(({ author, titleImage, price, title, place }) => {
// get the place from id
const { name, city } = places[place];
return {
authorUsername: author,
authorNickname: "",
authorImage: "",
titleImage,
title,
place: name,
city,
linkToProfile: "",
linkToPlace: "",
linkToStory: `www.ssdfsuy`,
storyPrice: price,
storyIsBought: ""
};
});
}
);
export const store = configureStore({
reducer: {
story: storiesReducer,
place: placesReducer
}
});
嗨,琳达,非常感谢你的回复和你提供的链接,你在理解如何处理数据方面帮了我很大的忙!