Skip to content

feat: RN 环境支持 sectionList 组件#2511

Open
yandadaFreedom wants to merge 19 commits into
masterfrom
feat-section-list-review
Open

feat: RN 环境支持 sectionList 组件#2511
yandadaFreedom wants to merge 19 commits into
masterfrom
feat-section-list-review

Conversation

@yandadaFreedom

Copy link
Copy Markdown
Collaborator

No description provided.


function isReactComponent (el) {
return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn
return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn && !isExtendComponentNode(el)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥需要?

itemLayouts: layouts,
getItemLayout: (data: any, index: number) => layouts[index]
}
}, [convertedListData, useListHeader, itemHeight.value, itemHeight.getter, sectionHeaderHeight.value, sectionHeaderHeight.getter, sectionFooterHeight.value, sectionFooterHeight.getter, listHeaderHeight.value, listHeaderHeight.getter])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

itemHeight.value, itemHeight.getter 为啥需要两种形式来着?


if (useListHeader) {
// 计算列表头部的高度
offset += listHeaderHeight.getter?.() || listHeaderHeight.value || 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类似这种不传递参数的getter直接让用户传递固定数值即可

}

// 遍历所有 sections
convertedListData.forEach((section: Section, sectionIndex: number) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看能不能改成在上面一次遍历listData就完成

@@ -0,0 +1,60 @@
const { EXTEND_COMPONENT_CONFIG } = require('../utils/const')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以基于现有的文件条件编译机制实现,不用单独添加resolver

@@ -0,0 +1 @@
<!-- sticky-header placeholder -->

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sticky-header和sticky-section是微信现有的组件,走内建组件注入的形式而不是走extends的形式

yandadaFreedom added 7 commits June 3, 2026 19:25
  - 将 sticky-header、sticky-section 接入模板内建组件转换
  - 调整 RN section-list 属性命名与头尾高度配置
  - 同步更新扩展组件、RN 组件文档及 mpx2rn skill 参考
  - 移除 sticky-header/sticky-section 占位组件
  - 更新 RN 组件文档中的 sticky-section/sticky-header 说明
  - 调整 section-list 头尾组件数据传递,确保 listHeaderData/listFooterData 更新触发渲染
  - 组合 style 移入 scrollAdditionalProps,避免被 innerProps.style 覆盖导致
    height/width/layoutStyle 丢失
  - 对齐 mpx-scroll-view,未显式设置 flex/flexGrow 时默认追加 flexGrow: 0,
    避免 RN ScrollView baseStyle 的 flexGrow: 1 把 height 拉伸成 100%
  ExtendComponentsPlugin 到 file 阶段解析

  - 将 ExtendComponentsPlugin 从 before-file
  -> resolve 改为 before-file -> file
  - 在 file 阶段直接重定向扩展组件的 path/
  relativePath
  - 跳过已处理的扩展组件请求,避免重复解析
}
}

function getComponentName (request) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个太复杂了
用path简单正则判断即可

@@ -0,0 +1,549 @@
import { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, memo } from 'react'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onRefresh / onEndReached / onScroll 未 useCallback,每次渲染都生成新引用,会被作为 prop 传到 SectionList,触发不必要的子树渲染。参考 mpx-scroll-view.tsx 内对 throttle/scroll 回调的处理。
scrollAdditionalProps.style 用 […] 数组字面量,每次渲染都产生新 ref,可考虑 useMemo。
useState(!!refresherTriggered) + useEffect 同步外部 prop 的写法:与 mpx-scroll-view.tsx:933-941 中现有方案保持一致即可,但可考虑直接受控(去掉 state)以减少状态机分支。
getGeneric 在每次 useMemo 中重新 memo(forwardRef(…)) 包一层:每次 generichash 或 key 变化都会创建新组件类型,挂载的子组件状态会丢失。建议把工厂提到模块顶层并缓存,或直接复用 __mpxGenericsMap 的引用。
hasOwn(style, 'flex') || hasOwn(style, 'flexGrow') ? null : { flexGrow: 0 }:可用 useMemo 缓存。

// 检查组件是否在配置中
const supportedModes = EXTEND_COMPONENTS[componentName]
if (!supportedModes) {
return callback(new Error(`Extended component "${componentName}" was not found. Available extended components: ${Object.keys(EXTEND_COMPONENTS).join(', ')}`))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return callback(),用 webpack 的 compilation.errors.push 而不是直接 reject resolve。下同

if (!position) return
const [sectionIndex, itemIndex] = position.split('_')
const targetSectionIndex = Number(sectionIndex) || 0
const targetItemIndex = itemIndex === 'header'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.3 scrollToIndex 对 footer 的 itemIndex 偏移可能有误
packages/webpack-plugin/lib/runtime/components/react/mpx-section-list.tsx:618-625

const targetItemIndex = itemIndex === 'header'
? 0
: itemIndex === 'footer'
? convertedListData[targetSectionIndex].data.length + 1
: Number(itemIndex) + 1
RN 的 SectionList.scrollToLocation 中 itemIndex 的含义:

0 = section header
1..data.length = data 项
data.length + 1 才会被识别为 section footer(在某些版本里则是越界)
这里 data.length + 1 实际算到了 data 之后的第一个槽位。如果 section 内 data 长度为 N:

第一项 itemIndex = 1,最后一项 itemIndex = N
footer 在不同 RN 版本中需要传 N + 1(有 header)或 N(无 header 时少一格)

@@ -0,0 +1 @@
<!-- section-list placeholder -->

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.4 占位 .mpx 文件可能被 loader 误处理
packages/webpack-plugin/lib/runtime/components/extends/section-list.mpx 内容是 。

理论上 resolver 在 before-file 阶段就把请求重定向到 dist/mpx-section-list.jsx,placeholder 永远不会进 loader。但要确保:

如果用户在 @mpx-options.target = 'web' 之类的环境下使用、或在 IDE 中错误地直接 import 这个文件,loader 处理这个空 mpx 会 crash 还是 warn?
推荐改为合法的最小 mpx 内容()或注释里写明用途,避免后续维护困惑:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants