为什么React组件作为子元素传入父组件时不会触发重新渲染?
问题根因
两种写法的核心差异是MyComponent对应的React元素的创建时机不同:
- 你把
<MyComponent />作为children传入父组件时,这个JSX是在父组件的外层执行的:也就是你调用render(<MyStateComponent><MyComponent /></MyStateComponent>)这一步就完成了React元素的创建。后续MyStateComponent触发重渲染时,接收的props.children是同一个引用的旧元素,React Diff判断子组件没有变更,就不会触发MyComponent的重渲染,所以renderCount和callback的调用次数最终停在1,测试断言失败。 - 你把
<MyComponent />直接写在MyStateComponent的返回值里时,每次父组件重渲染都会重新执行这段JSX、生成新的React元素,所以MyComponent会跟着父组件触发重渲染,测试断言自然符合预期。
调整方案
如果你需要测试作为children传入的组件在父组件重渲染时的表现,可以通过给传入的子组件绑定可变props的方式触发重渲染,示例逻辑如下:
function MyStateComponent({ children }: PropsWithChildren<{}>) { const forceUpdate = useReducer(() => ({}), {})[1] as () => void useEffect(() => { (async function asyncEffect() { await delay(10000); forceUpdate() })() }, []) // 克隆children并传入可变的key/prop触发重渲染 return <>{React.cloneElement(children as React.ReactElement, { updateKey: Date.now() })}</>; }
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

