Skip to content

iOS设备 RN新架构 0.82.1 pull-to-refresh 循环刷新 #83

@looooker

Description

@looooker

iOS 端使用 @sdcx/pull-to-refresh 提供的 RefreshControl 后,出现「按钮点击或编程式设置 refreshing=true 时反复刷新」的现象。
setRefreshing(true);

AI 分析的结论

@sdcx/pull-to-refresh 的 iOS Fabric 实现(RNPullToRefreshHeader.mm)在响应 props.refreshing 变化时,无论触发源是用户下拉手势还是 JS 端编程式设置,最终都会走到 settleToRefreshing 并在 0.2 秒动画 completion 中反向 emit onRefresh 事件

// updateProps: 接到 JS 层 refreshing=true → 调用 setRefreshing:YES
- (void)setRefreshing:(BOOL)refreshing {
  if (refreshing) { [self beginRefreshing]; }
  else { [self endRefreshing]; }
}
- (void)beginRefreshing { [self setState:RNRefreshStateRefreshing]; }

- (void)setState:(RNRefreshState)state {
  ...
  if (state == RNRefreshStateRefreshing) {
    [self settleToRefreshing];          // 用户手势 / JS props 走同一条路径
    return;
  }
  ...
}

- (void)settleToRefreshing {
  [self animateToRefreshingState:^(BOOL finished) {
    [self eventEmitter].onStateChanged({...RNRefreshStateRefreshing});
    [self eventEmitter].onRefresh({});  // ← 任意来源都 emit
  }];
}

当业务页面同时把同一个 refresh 函数挂到 <Pressable onPress><RefreshControl onRefresh>,并且该函数内部又会 setRefreshing(true) 时,就形成「setRefreshing(true) → native settleToRefreshing → 反向 emit onRefresh → JS 端再次调用 refresh() → setRefreshing(true)」的循环。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions