ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Enzyme ReactWrapper.reduceRight 深度解析:从右向左折叠节点集合

Enzyme ReactWrapper.reduceRight 深度解析:从右向左折叠节点集合 Enzyme ReactWrapper.reduceRight 深度解析从右向左折叠节点集合【免费下载链接】enzymeJavaScript Testing utilities for React项目地址: https://gitcode.com/gh_mirrors/en/enzymereduceRight是 Enzyme 中ReactWrapper以及ShallowWrapper提供的集合归约方法它把包装器Wrapper内匹配到的所有节点从右向左折叠fold成单个值。本文以 reduceRight 官方 API 文档 为骨架结合仓库源码实现与共享测试用例帮助你掌握该方法的签名、参数语义、遍历顺序、initialValue省略时的行为以及它与reduce、forEach、map等兄弟方法的差异从而在断言与数据汇总场景中写出准确、可维护的测试代码。方法签名与核心语义.reduceRight(fn[, initialValue]) AnyreduceRight对包装器中的每一个节点应用传入的归约函数fn最终把整个集合折叠为单个值。与.reduce最大的区别在于处理顺序.reduce从左到右left to right处理节点.reduceRight从右到左right to left处理节点即先处理集合中最后一个节点。每个被处理的节点都会以ReactWrapper的形式传入回调这意味着在归约过程中你依然可以使用prop()、text()、hasClass()等完整的 Wrapper API 读取节点信息。参数详解1.fnFunction必填一个归约函数集合中的每个节点都会执行一次。回调签名如下参数类型含义valueT上一次调用该函数返回的值累积值nodeReactWrapper当前被处理节点的单节点包装器indexNumber当前被处理节点在集合中的索引注意node始终是一个ReactWrapper而不是原始 React 元素因此可以直接调用node.prop(amount)、node.text()等方法来提取信息。2.initialValueT可选提供时作为第一次调用fn时的第一个参数value遍历从集合的第一个最右侧的节点开始省略时集合中第一个被处理的节点即最右侧节点会直接作为value传入第一次调用而回调中的node从集合的第二个节点开始此时fn只会被调用n - 1次n为节点总数。这一点与原生Array.prototype.reduceRight的规则完全一致可以视为其 Wrapper 语义的等价封装。返回值T归约函数累积得到的最终值。返回值的具体类型由fn的返回值决定——可以是数字、字符串、对象、数组等任何类型。原文档中“Returns an array of the returned values from the mapping function...”的描述沿用了模板措辞实际语义是返回单个归约结果而非数组数组形态的收集更适合用.map。完整示例对子组件 props 求和原文档给出了最典型的应用场景——对多个子组件的amount属性从右向左累加function Foo() { return ( div Bar amount{2} / Bar amount{4} / Bar amount{8} / /div ); }const wrapper mount(Foo /); const total wrapper.find(Bar).reduceRight((amount, n) amount n.prop(amount), 0); expect(total).to.equal(14);执行过程分析wrapper.find(Bar)得到包含 3 个Bar节点的ReactWrapper提供initialValue 0第一次调用fn时value 0、node为最右侧的Bar amount{8} /返回0 8 8第二次调用value 8、node为中间的Bar amount{4} /返回12第三次调用value 12、node为最左侧的Bar amount{2} /返回14。如果将同样的调用换成.reduce虽然最终累加结果同样是14但中间过程的处理顺序完全相反当累加操作不具备交换律如字符串拼接、对象合并、栈式运算时结果会截然不同。源码实现以Array.prototype.reduceRight为底层在仓库的 ReactWrapper.js 实现 中reduceRight的完整实现如下reduceRight(fn, initialValue undefined) { if (arguments.length 1) { return this.getNodesInternal().reduceRight( (accum, n, i) fn.call(this, accum, this.wrap(n), i), initialValue, ); } return this.getNodesInternal().reduceRight((accum, n, i) fn.call( this, i 1 ? this.wrap(accum) : accum, this.wrap(n), i, )); }从源码结构可以看出几个关键实现事实底层直接委托给原生数组方法内部节点先通过getNodesInternal()取出为数组再调用Array.prototype.reduceRight完成遍历因此遍历顺序、initialValue省略时的首节点吞并规则都由 ECMAScript 原生语义保证。节点被this.wrap(n)包装每次回调收到的node都是this.wrap(n)的结果即一个以当前ReactWrapper为根的ReactWrapper实例这保证了回调内部可以继续使用 Wrapper 的全部实例方法。this上下文透传回调通过fn.call(this, ...)调用this指向调用reduceRight的原始ReactWrapper实例与.forEach、.map的行为保持一致。省略initialValue时的特判i 1 ? this.wrap(accum) : accum这一行说明当未提供初始值时原生reduceRight会先把最后一个原始节点作为首个accum而酶在此处将其包装为ReactWrapper后再交给用户回调确保回调收到的value和node都是 Wrapper 形态。同样的实现逻辑也存在于ShallowWrapper中参见 ShallowWrapper.js 的 reduceRight 实现因此该方法在浅渲染场景下同样可用对应文档见 ShallowWrapper.reduceRight。测试用例验证的行为契约仓库中的共享测试 reduceRight.jsx 为ReactWrapper与ShallowWrapper两种包装器共同提供契约验证分别被 ReactWrapper-spec.jsx 与 ShallowWrapper-spec.jsx 引用可以从测试断言中提取出以下行为契约1. 方法签名长度——expect(Wrapper.prototype.reduceRight).to.have.lengthOf(1)方法声明的形参个数为 1仅fninitialValue通过arguments.length判断而不是显式形参。2. 逆序遍历顺序——测试对bax、bar、baz三个节点调用reduceRight断言回调接收顺序为baz → bar → baxhasClass(baz)在第一次调用中为true且每次回调的第一个参数都是Wrapper实例wrapper.find(.foo).reduceRight(spy, 0); expect(spy.args[0][1].hasClass(baz)).to.equal(true); expect(spy.args[1][1].hasClass(bar)).to.equal(true); expect(spy.args[2][1].hasClass(bax)).to.equal(true);3. 累积对象归约——测试用reduceRight把节点集合折叠成一个以id为键、className为值的对象证明归约结果可以是对象等任意类型const result wrapper.find(.foo).reduceRight((obj, n) { obj[n.prop(id)] n.prop(className); return obj; }, {}); expect(result).to.eql({ bax: foo qoo, bar: foo boo, baz: foo hoo });4. 省略initialValue——测试在省略初始值的情况下执行[].concat(acc, n, ...)折叠最终结果[three, two, counter, one, counter]清楚地表明首轮调用直接把最右侧节点three作为累积值随后依次处理two、one这正是右折叠语义的体现。相关方法对比与选用建议方法遍历方向返回值适用场景.reduce左 → 右单值T与处理顺序无关的求和、求积、拼接等.reduceRight右 → 左单值T依赖逆序的归约如栈式运算、逆序拼接、从后向前合并状态.forEach左 → 右ReactWrapper返回自身对每个节点执行副作用断言.map左 → 右ArrayAny把每个节点投影为新数组选用要点当你需要的是“每个节点 → 一个结果”的变换用.map当你需要对每个节点执行断言且不关心返回值用.forEach当你需要把整个集合折叠为单个值时再考虑.reduce与.reduceRight并根据归约运算是否依赖节点顺序决定方向——凡是“从最后一个节点开始处理”更自然的场景例如逆序合并字符串、实现右结合运算.reduceRight是更贴切的表达。小结ReactWrapper.reduceRight是原生Array.prototype.reduceRight在 Enzyme 包装器体系中的等价物它按从右到左的顺序遍历节点集合为每个节点提供ReactWrapper形态的回调参数支持可选initialValue并通过fn.call(this, ...)保留原始实例上下文。掌握它意味着你在测试中可以对一组匹配节点进行任意方向的归约聚合无论是统计 props 总和、逆序拼接文本还是把节点集合折叠为对象结构都能用一行清晰的表达式完成。【免费下载链接】enzymeJavaScript Testing utilities for React项目地址: https://gitcode.com/gh_mirrors/en/enzyme创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表