enter image description here

正如您在图像上看到的那样,获取数据并将其显示在屏幕上后,橙色按钮(在中心)出现1秒,然后消失.

组件代码:

const Home: FC = () => {
    const { pizzas, loading, error, count } = useAppSelector(
        (state) => state.pizzas
    )
    const { categoryID, searchValue, currentPage, sortNameObj } =
        useAppSelector((state) => state.filter)
    const dispatch = useAppDispatch()

    const handleChangeCategory = useCallback((index: number) => {
        dispatch(setCategoryID(index))
        dispatch(setCurrentPage(1))
    }, [])

    const handleChangePage = (page: number) => {
        dispatch(setCurrentPage(page))
    }

    const pizzaList = pizzas?.map((item) => {
        const pizzaImg = pizzaImagesMiddle[item.title]

        return <PizzaCard key={item.id} item={item} pizzaImg={pizzaImg} />
    })

    const skeletons = [...new Array(4)].map((_, index) => (
        <PizzaSkeleton key={index} />
    ))

    const loadedPizzas = loading ? skeletons : pizzaList

    useEffect(() => {
        dispatch(fetchPizzas())
    }, [categoryID, searchValue, sortNameObj, currentPage])

    if (error) {
        return <EmptyResult title='Произошла ошибка' />
    }

    if (!loading && (!pizzas || pizzas?.length === 0)) {
        return <EmptyResult title='Пиццы не найдены' />
    }

    return (
        <div className={styles.home__container}>
            <div className={styles.content__header}>
                <Categories
                    handleChangeCategory={handleChangeCategory}
                    value={categoryID}
                />
                <Sort sortNameObj={sortNameObj} />
            </div>
            <h2>Все пиццы</h2>
            <section className={styles.content__list}>{loadedPizzas}</section>
            <Pagination
                handleChangePage={handleChangePage}
                currentPage={currentPage}
                itemsLength={count}
            />
        </div>
    )
}

这是因为在条件if (!loading && (!pizzas || pizzas?.length === 0))时判断披萨长度.不判断空长if (!loading && !pizzas),一切顺利.但我需要判断数组是否为空.

默认情况下,披萨长度为空(因此在获取数据之前我有空数组)

披萨片:

const initialState: PizzasState = {
    pizzas: [],
    loading: false,
    error: null,
    count: 0
}

const pizzasSlice = createSlice({
    name: 'pizzas',
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        builder.addCase(fetchPizzas.pending, (state) => {
            state.loading = true;
            state.pizzas = [];
            state.error = null;
            state.count = 0
        });
        builder.addCase(fetchPizzas.fulfilled, (state, action) => {
            state.pizzas = action.payload.items;
            state.error = null;
            state.count = action.payload.count;
            state.loading = false
        });
        builder.addCase(fetchPizzas.rejected, (state, action) => {
            state.pizzas = [];
            state.count = 0;
            if (action.payload) {
                state.error = action.payload.message
            } else {
                state.error = action.error.message
            };
            state.loading = false
        })
    }
})

问:如何正确避免闪烁<EmptyResult/> 1秒?

推荐答案

Issue

loading为真且pizzas状态为假或空时,当前显示EmptyResult组件.pizzas状态最初为空,当fetchPizzas操作挂起时也被设置为[].

Solution

如果您只想在加载数据后显示EmptyResult,则从[] -"已获取数据并为空"和[....] -"已获取数据并为空"中 Select different值,以区分状态和加载条件.这里使用undefinednull是有效的 Select ,以指示数据尚未被获取/加载,并且很容易在UI中判断.

const initialState: PizzasState = {
  pizzas: undefined, // <-- initially undefined
  loading: false,
  error: null,
  count: 0,
};

const pizzasSlice = createSlice({
  name: 'pizzas',
  initialState,
  extraReducers: (builder) => {
    builder.addCase(fetchPizzas.pending, (state) => {
      state.loading = true;
      // state.pizzas = []; // <-- Don't update yet
      state.error = null;
      state.count = 0
    });
    builder.addCase(fetchPizzas.fulfilled, (state, action) => {
      state.pizzas = action.payload.items; // <-- update to "loaded" value
      state.error = null;
      state.count = action.payload.count;
      state.loading = false;
    });
    builder.addCase(fetchPizzas.rejected, (state, action) => {
      state.pizzas = []; // <-- update to "loaded" value
      state.count = 0;
      state.error = action.payload
        ? action.payload.message
        : action.error.message;
      state.loading = false;
    });
  },
});

更新UI以判断undefined/null加载的数据.

const skeletons = [...new Array(4)].map((_, index) => (
  <PizzaSkeleton key={index} />
));

const Home: FC = () => {
  const { pizzas, loading, error, count } =
    useAppSelector((state) => state.pizzas);
  const { categoryID, searchValue, currentPage, sortNameObj } =
    useAppSelector((state) => state.filter);
  const dispatch = useAppDispatch();

  const handleChangeCategory = useCallback((index: number) => {
    dispatch(setCategoryID(index));
    dispatch(setCurrentPage(1));
  }, []);

  useEffect(() => {
    dispatch(fetchPizzas())
  }, [categoryID, searchValue, sortNameObj, currentPage])

  const handleChangePage = (page: number) => {
    dispatch(setCurrentPage(page));
  };

  if (error) {
    return <EmptyResult title='Произошла ошибка' />;
  }

  // Check if pizzas is a defined array and empty
  if (!loading && (Array.isArray(pizzas) && !pizzas.length)) {
    return <EmptyResult title='Пиццы не найдены' />;
  }

  return (
    <div className={styles.home__container}>
      <div className={styles.content__header}>
        <Categories
          handleChangeCategory={handleChangeCategory}
          value={categoryID}
        />
        <Sort sortNameObj={sortNameObj} />
      </div>
      <h2>Все пиццы</h2>
      <section className={styles.content__list}>
        {loading
          ? skeletons
          : pizzas?.map((item) => (
            <PizzaCard
              key={item.id}
              item={item}
              pizzaImg={pizzaImagesMiddle[item.title]}
            />
          ))
        }
      </section>
      <Pagination
        handleChangePage={handleChangePage}
        currentPage={currentPage}
        itemsLength={count}
      />
    </div>
  );
};

Javascript相关问答推荐

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

我试图实现用户验证的reduxstore 和操作中出了什么问题?

如何在不创建新键的情况下动态更改 map 中的项目?

Chromium会将URL与JS一起传递到V8吗?

处理时间和字符串时MySQL表中显示的日期无效

制作钢琴模拟器,并且在控制台中不会执行或显示该脚本

PDF工具包阿拉伯字体的反转数字

在运行时使用Next JS App Router在服务器组件中运行自定义函数

使用领域Web SDK的Vite+Vue应用程序中的Web程序集(WASM)错误

在forEach循环中获取目标而不是父对象的属性

如何发送从REST Api收到的PNG数据响应

更新动态数据中对象或数组中的所有值字符串

查询参数中的JAVASCRIPT/REACT中的括号

让chart.js饼图中的一个切片变厚?

更新Redux存储中的对象数组

匹配一个或多个可选重复的特定模式

重新呈现-react -筛选数据过多

我在哪里添加过滤器值到这个函数?

如何将字符串拆分成单词并跟踪每个单词的索引(在原始字符串中)?

如果未定义,如何添加全局变量