何时需要调用wrapper.update()?外部更新含义及适用场景有哪些?
Enzyme 包装得到的 wrapper 本质是组件渲染时React树的快照,本身不会主动监听React树的重渲染行为。
文档里的「外部」是相对于Enzyme wrapper的内置API定义的:所有不通过当前wrapper自带方法触发的组件更新,都属于外部因素。这类更新发生后Enzyme无法自动感知,内部存的快照和真实React树会出现不一致,就需要手动调用 .update() 完成同步。
你提到的属性变更要分情况:通过Enzyme自带的 wrapper.setProps() 修改props时,方法内部已经自动同步了快照,不需要额外调用update;只有当props变更来自wrapper外部(比如父组件自行更新传参、根节点重渲染传入新属性),才属于文档说的外部因素。
只要是通过 setProps()、setState()、simulate() 这类Enzyme原生API同步触发的更新,都不需要手动调 .update()。
wrapper.update() 的常见场景 - 组件异步副作用触发的更新
组件在生命周期、useEffect、事件回调里跑的异步逻辑(接口请求、定时器、Promise回调等),只要更新不是Enzyme API同步触发的,等异步逻辑跑完、状态更新后,都得手动同步快照。既包括组件挂载后自动执行的异步副作用,也包括通过wrapper.instance()直接调用类组件异步方法的场景。
test('异步拉取数据后渲染列表', async () => { const wrapper = mount(<ListContainer />) // 直接调用实例上的异步请求方法 wrapper.instance().loadData() await waitForRequestComplete() // 同步最新组件树,否则找不到渲染后的列表项 wrapper.update() expect(wrapper.find('.list-item')).toHaveLength(10) })
外部全局状态变更触发的更新
如果组件依赖Redux、MobX、全局事件总线、外部注入的Context这类Enzyme管不到的状态,测试里直接改这些状态(比如直接dispatch action、更新store、触发全局监听事件)导致组件重渲染时,需要手动同步。非Enzyme方法触发的DOM事件
用原生dispatchEvent、第三方事件模拟工具触发DOM事件(而不是Enzyme自带的simulate()方法)时,事件冒泡后React触发的组件更新对Enzyme来说属于外部变更,需要在事件触发后调用update。根节点重复渲染
如果测试里直接调用react-dom的渲染方法,在同一个DOM节点上重复渲染根组件(比如模拟外部框架重新挂载应用),Enzyme持有的旧快照不会自动更新,得手动同步。
注意:
.update()只负责同步快照,不会主动触发组件重渲染。别在Enzyme API触发的同步更新后面冗余调用,不仅没用,还可能掩盖异步时序问题。
内容的提问来源于stack exchange,提问作者Lin Du

