我有三片ProductSlice,CategorySliceBrandSlice片.每个切片有createAsyncThunk个,对产品、类别和品牌进行提取请求.

CategorySlice(BrandSlice个相同):

export const fetchCategories = createAsyncThunk('category/fetchCategories', async () => {
  const response = await fetch(`${BASE_URL}/categories.json`);
  const data = await response.json();
  const categories: Category[] = handleObj(data);
  return categories;
});

    builder.addCase(fetchCategories.fulfilled, (state, { payload }) => {
      state.categories = payload;
      state.isLoading = false;
    });

应用程序组件分派三个FETCH请求.

  useEffect(() => {
     dispatch(fetchCategories());
     dispatch(fetchProducts());
     dispatch(fetchBrands()); 
  }, [dispatch]);

我需要从品牌和类别中获得数据.然后获取产品的数据,并向每个产品添加一些数据,然后才将其设置为ProducSlice状态.数据应该来自品类和品牌.我试着在ProductSlice-createAsyncThunk中这样做:

export const fetchProducts = createAsyncThunk<Product[], void, { state: RootState }>(
  'product/fetchProducts',
  async (_, { getState }) => {
    const response = await fetch(`${BASE_URL}/products.json`);
    const data = await response.json();
    const products: Product[] = handleObj(data);

    const { brands } = await getState().brand;
    const { categories } = await getState().category;

    const productsWithUpdatedBrandsAndCategories = products.map((product) => {
      const category = categories.find((category) => category.id === product.category.id);
      const brand = brands.find((brand) => brand.id === product.brand.id);

      if (!category && !brand) return product;

      return {
        ...product,
        category: {
          ...category,
          name: category && category.name,
        },
        brand: {
          ...brand,
          name: brand && brand.name,
        },
      };
    }) as Product[];

    return productsWithUpdatedBrandsAndCategories;
  }
);

问题是,有时,thunk中ProductSlice中的品牌或类别是空数组(我的意思是,当数据不是来自其他切片时,thunk就会触发……所以productsWithUpdatedBrandsAndCategories什么都不做).那该怎么处理呢?

推荐答案

在能够调度fetchProducts以使品牌和类别状态可用之前,似乎存在对fetchCategoriesfetchBrands以及后续状态更新的依赖.

我建议进行一点重构,分派前两个操作并等待它们解决,然后再分派第三个操作.

示例:

useEffect(() => {
  const fetchData = async () => {
    try {
      // fetch brands and categories and wait for actions to resolve
      await Promise.all([
        dispatch(fetchBrands()),
        dispatch(fetchCategories()),
      ]);

      // now fetch products
      dispatch(fetchProducts());
    } catch(error) {
      // handle or ignore errors?
    }
  };
  
  fetchData();
}, [dispatch]);

...

export const fetchProducts = createAsyncThunk<Product[], void, { state: RootState }>(
  'product/fetchProducts',
  async (_, { getState }) => {
    const response = await fetch(`${BASE_URL}/products.json`);
    const data = await response.json();
    const products: Product[] = handleObj(data);

    const {
      brand: { brands },
      category: { categories },
    } = getState();

    const productsWithUpdatedBrandsAndCategories = products.map((product) => {
      const category = categories.find((category) => category.id === product.category.id);
      const brand = brands.find((brand) => brand.id === product.brand.id);

      if (!category && !brand) return product;

      return {
        ...product,
        category: {
          ...category,
          name: category && category.name,
        },
        brand: {
          ...brand,
          name: brand && brand.name,
        },
      };
    }) as Product[];

    return productsWithUpdatedBrandsAndCategories;
  }
);

Reactjs相关问答推荐

有没有方法覆盖NextJS 14中的布局?

我想删除NextJs中的X轴标签APEXCHARTS

为多租户SSO登录配置Azure AD应用程序

在REACT-RUTER-DOMV6中使用通用页面包装组件有问题吗?

对搜索引擎优化来说,react 头盔的异步足够了吗?

用于获取带有事件处理程序的API的动态路由

如何动态地改变<; Select >;React和Tailwind元素?

定位数组中的一项(React、useState)

Javascript - 正则表达式不适用于 MAC OS - 编码?

PWA:注册事件侦听器不会被触发

我可以同时使用 Gatsby 和 NEXT.JS 吗?

如何在 React 过滤器中包含价格过滤器逻辑?

需要先填写依赖输入字段,以便其他人工作

next js 13 在获取中使用标头时动态渲染而不是静态渲染?

ReactJs 行和列

如何使用react 路由将 url 参数限制为一组特定的值?

在 React 中,为什么不能向空片段添加键(短语法)?

在 redux 状态更改时更新react 按钮禁用状态

在 Redux 中更新布尔状态时出错

在 React 中访问作为 prop 传递的状态变量