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

ReactXP高阶组件(HOC)状态变更时无法渲染的问题

实现ReactXP全屏加载Spinner的TypeScript高阶组件(HOC)

我来帮你补全这个全屏加载Spinner的HOC实现,结合你已经写的ReactXP和TypeScript代码,完整的实现应该是这样的:

import RX = require('reactxp');

const styles = {
  semiTransparentBlackBackground: RX.Styles.createViewStyle({
    backgroundColor: 'rgba(0, 0, 0, 0.7)',
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: 1000,
  }),
  spinnerContainer: RX.Styles.createViewStyle({
    padding: 16,
    backgroundColor: '#fff',
    borderRadius: 8,
  }),
};

export interface WithFullScreenSpinnerProps {
  // 传入控制Spinner显示的状态
  isLoading: boolean;
}

export interface WithFullScreenSpinnerState {
  showSpinner: boolean;
}

// 定义高阶组件的类型,确保类型安全
type HOC = <P extends WithFullScreenSpinnerProps>(
  Component: RX.ComponentType<P>
) => RX.ComponentType<Omit<P, keyof WithFullScreenSpinnerState>>;

const withFullScreenSpinner: HOC = (WrappedComponent) => {
  return class extends RX.Component<
    Omit<WithFullScreenSpinnerProps, keyof WithFullScreenSpinnerState>,
    WithFullScreenSpinnerState
  > {
    constructor(props: any) {
      super(props);
      this.state = {
        showSpinner: false,
      };
    }

    // 监听isLoading属性变化,同步Spinner状态
    componentDidUpdate(prevProps: any) {
      if (this.props.isLoading !== prevProps.isLoading) {
        this.setState({ showSpinner: this.props.isLoading });
      }
    }

    render() {
      const { showSpinner } = this.state;
      return (
        <RX.View style={RX.Styles.createViewStyle({ flex: 1 })}>
          {/* 渲染原组件 */}
          <WrappedComponent {...this.props} />
          {/* 加载状态显示Spinner */}
          {showSpinner && (
            <RX.View style={styles.semiTransparentBlackBackground}>
              <RX.View style={styles.spinnerContainer}>
                <RX.Spinner
                  style={RX.Styles.createSpinnerStyle({
                    color: '#333',
                    size: 'large',
                  })}
                />
                {/* 可选:添加加载提示文本 */}
                <RX.Text
                  style={RX.Styles.createTextStyle({
                    marginTop: 12,
                    color: '#333',
                    fontSize: 16,
                  })}
                >
                  加载中...
                </RX.Text>
              </RX.View>
            </RX.View>
          )}
        </RX.View>
      );
    }
  };
};

export default withFullScreenSpinner;

使用示例

你可以这样在业务组件中使用这个HOC:

import RX = require('reactxp');
import withFullScreenSpinner from './WithFullScreenSpinnerHOC';

interface MyListProps {
  listData: { id: number; title: string }[];
  isLoading: boolean;
}

class MyList extends RX.Component<MyListProps> {
  render() {
    return (
      <RX.View style={RX.Styles.createViewStyle({ flex: 1, padding: 20 })}>
        {this.props.listData.map(item => (
          <RX.Text key={item.id} style={RX.Styles.createTextStyle({ marginBottom: 8 })}>
            {item.title}
          </RX.Text>
        ))}
      </RX.View>
    );
  }
}

// 用HOC包裹组件,获得加载状态控制能力
export default withFullScreenSpinner(MyList);

关键细节说明

  • 全屏覆盖:给背景容器添加了绝对定位和全屏尺寸,确保Spinner能覆盖整个页面内容,不会被其他元素遮挡。
  • 类型安全:使用TypeScript泛型和Omit工具类型,保证包裹后的组件不会丢失原组件的属性,同时明确HOC的输入输出类型。
  • 状态同步:通过componentDidUpdate监听isLoading属性变化,自动更新Spinner的显示状态,无需手动维护。
  • 可定制性:你可以根据需求修改Spinner的颜色、大小,调整背景透明度,或者替换加载文本内容,适配不同的UI风格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:30:21