为什么React处理children时获取的key会带有.$前缀?
根本原因
你看到的.$前缀是React内部为了保证遍历返回的子元素key全局唯一自动添加的命名空间前缀,触发这个逻辑的核心原因是你调用了React.Children.map并返回了子元素本身:
React.Children.map不是普通的数组遍历方法,它是React专门用于处理嵌套、碎片化子元素的工具API,当你在它的回调中返回React元素时,React会自动给每个返回的元素拼接层级前缀到key上,避免不同层级子元素出现key重复的问题,你看到的.$就是这一步拼接的前缀。- 你最初的写法不会出现前缀,是因为你在
React.Children.map的回调中直接返回了key字符串,没有返回React元素,React不会对非元素返回值做key处理,拿到的就是用户定义的原始key。 - 后续你调整写法后,先调用
React.Children.map(children, child => child)返回了子元素数组,这时候数组里的所有元素的key已经被React加上了前缀,后续再遍历拿key自然会携带.$。
更稳妥的解决方案
不推荐手动替换前缀的方案,可能会出现边界情况(比如用户自定义key本身就包含.$字符),可以用下面两种方案替代:
方案1:在React.Children.map回调中同时完成过滤和key收集
直接在第一次遍历的时候就判断props并收集key,避免二次处理被加了前缀的元素:
const keys = React.Children .map(children, (child) => { if ((child.props.shown ?? true) === false) return null return child.key }) .filter(Boolean)
方案2:将children转为普通数组后再操作
如果需要保留过滤后的子元素数组做其他用途,可以先把children转成普通数组再做过滤、取key操作,不会触发React的自动key前缀逻辑:
// 转成普通数组,保留原始key const childrenArray = Array.from(children) const activeChildren = childrenArray.filter(child => child.props.shown ?? true) const keys = activeChildren.map(child => child.key)
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

