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
  }
});

嗨,琳达,非常感谢你的回复和你提供的链接,你在理解如何处理数据方面帮了我很大的忙!