优雅的加载条——React版

优雅的加载条

React 应用中使用组件库的加载条(Loading Bar)并保持代码优雅,可以遵循以下步骤。以下示例将使用 Ant Design 组件库的 Spin 组件作为加载条示例,并通过组件化、状态管理和样式组织实现优雅的代码。

安装相应版本的Ant Design

npm install antd

简单场景

1.创建一个 Loading Wrapper 组件

创建一个通用的 Loading Wrapper 组件,用于在任何需要加载状态的地方使用

import React from 'react';
import { Spin } from 'antd';
import PropTypes from 'prop-types';

//加载组件
const LoadingWrapper = ({ loading, children }) => {
  return (
    <Spin spinning={loading}>
      {children}
    </Spin>
  );
};

LoadingWrapper.propTypes = {
  loading: PropTypes.bool.isRequired,
  children: PropTypes.node.isRequired,
};

export default LoadingWrapper;

2.使用 Loading Wrapper 组件

在需要显示加载状态的组件中使用 LoadingWrapper 组件

import React, { useState, useEffect } from 'react';
import { List, message } from 'antd';
import LoadingWrapper from './LoadingWrapper';
import axios from 'axios';

const DataFetchingComponent = () => {
  const [loading, setLoading] = useState(true);//初始值要开启加载条
  const [data, setData] = useState([]);

  useEffect(() => {
    axios.get('/api/data')
      .then(response => {
        setData(response.data);
        setLoading(false);//关闭加载条
      })
      .catch(error => {
        message.error('Failed to fetch data');
        setLoading(false);
      });
  }, []);

  return (
    <LoadingWrapper loading={loading}>
      <List
        dataSource={data}
        renderItem={item => <List.Item>{item}</List.Item>}
      />
    </LoadingWrapper>
  );
};

export default DataFetchingComponent;

复杂场景

对于更复杂的应用,可以使用全局状态管理工具(如 Redux 或 Context API)来管理加载状态。

1. 使用 Context API 进行全局加载状态管理

import React, { createContext, useState, useContext } from 'react';
//创建一个 Loading Context:
const LoadingContext = createContext();

export const useLoading = () => useContext(LoadingContext);

export const LoadingProvider = ({ children }) => {
  const [loading, setLoading] = useState(false);

  return (
    <LoadingContext.Provider value={{ loading, setLoading }}>
      {children}
    </LoadingContext.Provider>
  );
};
//在顶层组件中使用 LoadingProvider
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { LoadingProvider } from './LoadingContext';

ReactDOM.render(
  <LoadingProvider>
    <App />
  </LoadingProvider>,
  document.getElementById('root')
);

//在组件中使用全局加载状态
import React, { useEffect } from 'react';
import { List, message } from 'antd';
import LoadingWrapper from './LoadingWrapper';
import axios from 'axios';
import { useLoading } from './LoadingContext';

const DataFetchingComponent = () => {
  const { loading, setLoading } = useLoading();
  const [data, setData] = useState([]);

  useEffect(() => {
    setLoading(true);//初始值为开启加载
    axios.get('/api/data')
      .then(response => {
        setData(response.data);
        setLoading(false);
      })
      .catch(error => {
        message.error('Failed to fetch data');
        setLoading(false);
      });
  }, [setLoading]);

  return (
    <LoadingWrapper loading={loading}>
      <List
        dataSource={data}
        renderItem={item => <List.Item>{item}</List.Item>}
      />
    </LoadingWrapper>
  );
};

export default DataFetchingComponent;

2.借助Redux进行状态管理

安装 Redux 和相关库:
npm install redux react-redux @reduxjs/toolkit
创建 Redux Store
import { configureStore, createSlice } from '@reduxjs/toolkit';

const loadingSlice = createSlice({
  name: 'loading',
  initialState: false,
  reducers: {
    setLoading: (state, action) => action.payload,
  },
});

export const { setLoading } = loadingSlice.actions;

const store = configureStore({
  reducer: {
    loading: loadingSlice.reducer,
  },
});

export default store;
在顶层组件中提供 Redux Store
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

在组件中使用 Redux 状态
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { List, message } from 'antd';
import LoadingWrapper from './LoadingWrapper';
import axios from 'axios';
import { setLoading } from './store';

const DataFetchingComponent = () => {
  const loading = useSelector((state) => state.loading);
  const dispatch = useDispatch();
  const [data, setData] = useState([]);

  useEffect(() => {
    dispatch(setLoading(true));
    axios.get('/api/data')
      .then(response => {
        setData(response.data);
        dispatch(setLoading(false));
      })
      .catch(error => {
        message.error('Failed to fetch data');
        dispatch(setLoading(false));
      });
  }, [dispatch]);

  return (
    <LoadingWrapper loading={loading}>
      <List
        dataSource={data}
        renderItem={item => <List.Item>{item}</List.Item>}
      />
    </LoadingWrapper>
  );
};

export default DataFetchingComponent;

知识加油站

Redux和Context API 的关系

Redux 和 Context API 都是用于状态管理的工具,但它们有不同的特点和使用场景。以下是它们的主要区别和关系:

Redux

Redux 是一个流行的状态管理库,提供了一个集中式的状态存储和不可变状态更新的机制。Redux 适用于大型应用程序,具有以下特点:

  • 集中式状态管理:所有的状态存储在一个单独的 store 中,便于调试和管理。
  • 不可变状态更新:通过 actions 和 reducers 更新状态,确保状态不可变。
  • 中间件支持:支持异步 actions 和其他中间件(如 redux-thunk、redux-saga)来处理复杂的逻辑。
  • 丰富的生态系统:有许多工具和库可以与 Redux 集成,如 Redux DevTools。

Context API

Context API 是 React 提供的内置状态管理解决方案,适用于较小或中等规模的应用程序。它的特点包括:

  • 简洁易用:内置于 React 中,无需额外安装。
  • 组件树上下文传递:允许在组件树中传递数据,避免了 prop drilling。
  • 轻量级:适合简单的状态管理场景,特别是当状态变化不频繁时。

Redux 和 Context API 的关系

  • 使用场景:Redux 适用于复杂和大型应用程序,需要集中式状态管理和复杂的状态更新逻辑;Context API 则适用于较小和中等规模的应用程序,或需要简单状态传递的场景。
  • 复杂性:Redux 提供了更多的结构和工具来管理复杂的状态和逻辑,但也引入了更多的复杂性;Context API 更加简洁,适合轻量级的状态管理。
  • 性能:Context API 可能在频繁状态变化时导致性能问题,因为每次状态变化都会重新渲染使用该上下文的组件树;Redux 则通过连接(connect)和选择器(selectors)优化了这种问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值