如何在React Query Builder中添加额外字段并导出对应值?
在React Query Builder中实现带额外字段的值管理
要解决导出JSON时无法获取X/Y/Z值的问题,核心是将主值(2d/3d)与额外字段值合并为一个结构化对象存储,而非单独的字符串。以下是具体实现方案:
步骤1:修改自定义值编辑器,管理结构化状态
将值存储为包含type(主值)和额外字段的对象,在编辑器内部同步状态并更新父组件的onChange回调:
import { useState, useEffect } from 'react'; import { ValueEditor } from 'react-querybuilder'; const CustomValueEditor = (props) => { // 解析当前值:支持初始字符串或已结构化的对象 const parseValue = () => { if (typeof props.value === 'object' && props.value !== null) { return props.value; } return { type: props.value || '', x: '', y: '', z: '' }; }; const [valueObj, setValueObj] = useState(parseValue()); // 外部值更新时同步内部状态 useEffect(() => { setValueObj(parseValue()); }, [props.value]); // 处理主类型(2d/3d)的变化 const handleTypeChange = (newType) => { const newObj = { ...valueObj, type: newType }; // 非3d类型时移除z字段,避免冗余 if (newType !== '3d') delete newObj.z; setValueObj(newObj); props.onChange(newObj); }; // 处理X/Y/Z字段的变化 const handleExtraFieldChange = (field, value) => { const newObj = { ...valueObj, [field]: value }; setValueObj(newObj); props.onChange(newObj); }; switch (valueObj.type) { case "3d": return ( <div className='demo-space-x'> <ValueEditor {...props} value={valueObj.type} onChange={handleTypeChange} /> <input placeholder='X' value={valueObj.x || ''} onChange={(e) => handleExtraFieldChange('x', e.target.value)} /> <input placeholder='Y' value={valueObj.y || ''} onChange={(e) => handleExtraFieldChange('y', e.target.value)} /> <input placeholder='Z' value={valueObj.z || ''} onChange={(e) => handleExtraFieldChange('z', e.target.value)} /> </div> ); case "2d": return ( <div className='demo-space-x'> <ValueEditor {...props} value={valueObj.type} onChange={handleTypeChange} /> <input placeholder='X' value={valueObj.x || ''} onChange={(e) => handleExtraFieldChange('x', e.target.value)} /> <input placeholder='Y' value={valueObj.y || ''} onChange={(e) => handleExtraFieldChange('y', e.target.value)} /> </div> ); default: return <ValueEditor {...props} />; } };
步骤2:优化字段配置(可选)
添加valueFormatter让规则显示更直观,将结构化对象转换为可读字符串:
{ name: 'system', label: 'system', inputType: 'string', operators: [equal, notEqual, less, lessOrEqual, greater, greaterOrEqual], valueFormatter: (value) => { if (typeof value === 'object') { const parts = [value.type]; if (value.x) parts.push(`X:${value.x}`); if (value.y) parts.push(`Y:${value.y}`); if (value.z) parts.push(`Z:${value.z}`); return parts.join(' '); } return value; } }
效果说明
- 当用户选择
2d/3d时,会自动显示对应额外输入框,输入的值会与主类型合并为对象存储 - 导出JSON时,规则的
value字段会包含完整的结构化数据,示例如下:{ "combinator": "and", "rules": [ { "field": "system", "operator": "=", "value": { "type": "3d", "x": "15", "y": "25", "z": "35" } } ] }
内容的提问来源于stack exchange,提问作者Devid Mercer
相关产品推荐
相关产品推荐

