React中如何将Yup返回的点分隔对象路径转换为嵌套对象
实现方案
核心思路是将点分隔的路径字符串按.拆分成层级数组,从根对象开始逐层创建嵌套属性,直到路径最后一级赋值为true即可。
可直接复用的工具函数
function pathToNestedObject(path, leafValue = true) { const result = {} const keyChain = path.split('.') let currentLevel = result keyChain.forEach((key, index) => { const isLastLevel = index === keyChain.length - 1 if (isLastLevel) { currentLevel[key] = leafValue return } // 当前层级不存在对应属性时先初始化空对象 if (!currentLevel[key] || typeof currentLevel[key] !== 'object') { currentLevel[key] = {} } // 指针移动到下一层级 currentLevel = currentLevel[key] }) return result }
使用示例
传入示例路径调用函数:
const errPath = 'locationAvailability.availabilityPerDay.thursday.start' const errObj = pathToNestedObject(errPath)
得到的输出完全匹配目标结构:
{ locationAvailability: { availabilityPerDay: { thursday: { start: true } } } }
多错误路径合并方案
实际表单校验时Yup通常会返回多条错误路径,你可以配合深合并方法,把所有路径生成的嵌套对象合并为统一的表单错误对象:
// 如果你项目中使用lodash,可直接引入lodash/merge替代该深合并方法 function deepMerge(target, source) { for (const key in source) { if (source[key] && typeof source[key] === 'object') { target[key] = target[key] || {} deepMerge(target[key], source[key]) } else { target[key] = source[key] } } return target } // 示例:合并3条错误路径 const errorPathList = [ 'locationAvailability.availabilityPerDay.thursday.start', 'locationAvailability.availabilityPerDay.friday.end', 'basicInfo.contact' ] const formErrorState = errorPathList.reduce((mergedErr, path) => { return deepMerge(mergedErr, pathToNestedObject(path)) }, {})
补充说明:如果校验的是数组类型字段,Yup返回的路径会包含数字下标(例如
scheduleList.2.startTime),上述方法可以正常处理这类路径,数字字符串作为对象key不会影响React表单状态的读取和更新。
内容的提问来源于stack exchange,提问作者Nika Butikashvili
相关产品推荐
相关产品推荐

