如何在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
相关产品推荐
相关产品推荐

