You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中避免<EmptyResult/>组件短暂闪现1秒的问题?

解决React中
return (<EmptyResult/>)
组件短暂闪现的问题

问题根源

初始状态的判断逻辑混淆了**“未发起过数据请求”和“请求完成后无数据”**两种场景:

  • 初始时pizzas是空数组,loading为false,导致!loading && pizzas.length === 0条件直接成立,渲染了<EmptyResult/>。
  • 组件挂载后useEffect才触发fetchPizzas,在请求进入pending阶段(将loading设为true)前存在短暂时间差,这就造成了EmptyResult的闪现。

方案1:新增状态标记是否已发起过请求

通过在Redux状态中添加hasFetched字段,精准区分两种场景,是最严谨的解决方案。

修改Pizza Slice代码

在初始状态中新增hasFetched,并在请求发起时将其设为true:

const initialState: PizzasState = {
    pizzas: [],
    loading: false,
    error: null,
    count: 0,
    hasFetched: false // 新增:标记是否已发起过数据请求
}

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;
            state.hasFetched = true; // 发起请求后标记为已请求
        });
        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;
        })
    }
})

修改Home组件的判断逻辑

引入hasFetched并调整渲染条件,仅当请求已完成且无数据时才显示EmptyResult:

const { pizzas, loading, error, count, hasFetched } = useAppSelector(
    (state) => state.pizzas
)

// ... 其他代码保持不变

// 仅当请求已发起、加载完成且无数据时,才显示EmptyResult
if (!loading && hasFetched && (!pizzas || pizzas.length === 0)) {
    return <EmptyResult title='Пиццы не найдены' />
}

方案2:将初始loading状态设为true

这种方式更简洁,直接让页面初始就显示骨架屏,避免初始状态下渲染EmptyResult:

修改Pizza Slice初始状态

const initialState: PizzasState = {
    pizzas: [],
    loading: true, // 初始设为true,直接显示骨架屏
    error: null,
    count: 0
}

组件挂载后会直接渲染骨架屏,直到第一次请求完成,不会出现EmptyResult的闪现。缺点是如果用户网络极快,可能会看到骨架屏短暂显示,但相比EmptyResult的误导性闪现,这种体验更合理。

内容的提问来源于stack exchange,提问作者rgdzv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:05:13