-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Description
问题描述
有如下代码,静态编写多子组件,不会出现 key 警告
export function App({ name }) {
return (
<div>
<h1>{name}</h1>
<h1>{name}</h1>
<h1>{name}</h1>
</div>
)
}但是,如果使用动态的形式创建多个子组件,就会出现 key 警告
export function App({ name }) {
return (
<div>
{
[1,2,3].map(id => {
return <h2>{id}</h2>
})
}
</div>
)
}原理探索
那么在分析 JSX 代码的时候,对于静态多个子组件,会对其父组件使用 jsxs。而对于动态版本,则会使用 jsx

jsxs 和 jsx 函数定义在文件 packages/react-reconciler/src/ReactChildFiber.new.js

通过第四个参数控制,如果为 true,则会进入 validateChildKeys -> validateExplicitKey 提前设置 element._store.validated = true;。那么在 reconcileChildrenArray 阶段,warnForMissingKey 函数会在判断 !child._store || child._store.validated || child.key != null 提前返回(child._store.validated 为 true)
附 警告时调用堆栈
validateExplicitKey (index.js:formatted:2473)
validateChildKeys (index.js:formatted:2473)
jsxWithValidation (index.js:formatted:2473) <- 这里调用时,第四个参数为 false
App (App5.js:6)
renderWithHooks (index.js:formatted:2473)
mountIndeterminateComponent (index.js:formatted:2473)
beginWork (index.js:formatted:2473)
beginWork$1 (index.js:formatted:2473)
performUnitOfWork (index.js:formatted:2473)
workLoopSync (index.js:formatted:2473)
renderRootSync (index.js:formatted:2473)
performSyncWorkOnRoot (index.js:formatted:2473)
scheduleUpdateOnFiber (index.js:formatted:2473)
updateContainer (index.js:formatted:2473)
(anonymous) (index.js:formatted:2473)
unbatchedUpdates (index.js:formatted:2473)
legacyRenderSubtreeIntoContainer (index.js:formatted:2473)
render (index.js:formatted:2473)
(anonymous) (index.js:10)
./src/index.js (index.js:24)
__webpack_require__ (bootstrap:856)
fn (bootstrap:150)
1 (reportWebVitals.js:14)
__webpack_require__ (bootstrap:856)
checkDeferredModules (bootstrap:45)
webpackJsonpCallback (bootstrap:32)
(anonymous) (main.chunk.js:1)
Metadata
Metadata
Assignees
Labels
No labels
