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

