React开发SQL编辑器时UI参数与编辑器内容双向同步异常问题
问题根源
- 存在冗余的SQL状态:同时维护了
currentChartInfo.SQLQuery和textSql两个SQL存储源,currentChartInfo.SQLQuery仅在初始化时赋值,用户编辑SQL后不会同步更新,后续用它作为基准拼接参数时会直接覆盖用户自定义内容。 - 参数追加逻辑错误:修改参数名时直接遍历所有参数往SQL末尾拼接,没有做存在性校验,也没有保留用户原有SQL内容,既会导致参数重复,也会破坏用户已编写的内容。
- 状态更新时序错误:
updateProperty中遍历的是更新前的params数组,而非本次修改后的newProperties数组,导致新输入的参数名无法及时生效。
修复方案
- 统一SQL数据源:以
textSql作为SQL内容的唯一可信源,所有修改都直接更新textSql,同时同步currentChartInfo.SQLQuery保证其他逻辑可用。 - 重写参数更新逻辑:修改参数名时仅做增量操作,新增参数直接追加,修改已有参数则替换对应占位符,不触动用户其他SQL内容。
- 修正状态引用:所有参数操作都使用本次修改后的新参数数组,避免引用旧状态导致的异常。
核心代码修改示例
初始化逻辑调整
useEffect(() => { let sqlDefaultString = ''; sqlDefaultString = fromQuery.internal_name ? `SELECT * FROM \`${fromQuery.internal_name}__${fromQuery.items[0]}\` LIMIT 20` : ''; // 统一更新两个SQL状态,保证初始值一致 setTextSql(sqlDefaultString); setCurrentChartInfo(prev => ({ ...prev, SQLQuery: sqlDefaultString, })); },[fromQuery]);
参数更新逻辑重写
const updateProperty = (event, index, key) => { const newProperties = [...params]; const oldParamName = newProperties[index].name; const newVal = event?.target?.value || ''; newProperties[index][key] = newVal; // 仅修改参数名时才需要同步到SQL编辑器 if (key === 'name' && /^\w+$/i.test(newVal)) { let newSql = textSql; if (oldParamName) { // 已有旧参数名,直接替换对应占位符,不改动其他SQL内容 newSql = newSql.replaceAll(`{{${oldParamName}}}`, `{{${newVal}}}`); } else { // 新增参数,追加到SQL末尾 newSql += `{{${newVal}}}`; } // 同步更新两个SQL状态 setTextSql(newSql); setCurrentChartInfo(prev => ({ ...prev, SQLQuery: newSql, })) } setParams(newProperties); };
编辑器变更逻辑补充同步
const changeTextEditor = (valueEditor) => { const namesParams = arrayParamsExec(valueEditor); const newProperties = namesParams.map((pName) => { const valueNew = params.find(p => p.name === pName); return {name: pName, value: valueNew?.value || ''}; }); setParams(newProperties); setTextSql(valueEditor); // 同步更新currentChartInfo的SQL内容 setCurrentChartInfo(prev => ({ ...prev, SQLQuery: valueEditor, })) }
内容的提问来源于stack exchange,提问作者Albert Arias
相关产品推荐
相关产品推荐

