You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

输入特殊字符时reactable表格消失的问题及解决咨询

Reactable自定义过滤/搜索时表格消失问题解决方法

问题场景

使用reactable包配置了自定义过滤/搜索方法、正则规则,以及折叠重复行的函数,但出现以下异常:

  • 输入数字或正常文本时表格显示正常
  • 输入\、*等正则特殊字符,或输入无匹配内容的字符串时,表格直接消失,仅能通过刷新页面恢复

可复现代码如下:

library(reactable)
library(htmltools)

customsearch <-  JS('
function(rows, columnIds, filterValue) {
    let arrFilterValues = filterValue.split(" ");

    return rows.filter(function(row) {
        return arrFilterValues.map(function(e) {
            return columnIds.some(function(columnId) {
                return new RegExp(e,"i").test(row.values[columnId])
            });
        }).every(v => v === true);
    });
}')

customfilter <- JS('function(rows, columnId, filterValue) {
    let arrFilterValues = filterValue.split(" ");

    return rows.filter(function(row) {
        return arrFilterValues.map(function(e) {
                return new RegExp(e,"i").test(row.values[columnId])
        }).every(v => v === true);
    });
}')


reactable(iris,filterable=TRUE,searchable=TRUE,static=TRUE, rowStyle=JS("function(rowInfo, state) {
    const firstSorted = state.sorted[0]
    if (!firstSorted || firstSorted.id === 'Petal.Length') {
      const prevRow = state.pageRows[rowInfo.viewIndex - 1]
      if (prevRow && rowInfo.values['Petal.Length'] === prevRow['Petal.Length']) {
        return { visibility: 'collapse' }
      }
    }
  }"), searchMethod = customsearch, defaultColDef=colDef(filterMethod=customfilter, html=TRUE))

问题原因

  1. 正则特殊字符未转义:当输入\、*这类正则元字符时,new RegExp(e,"i")会因语法错误抛出异常,导致过滤函数无法返回有效行,表格无数据可渲染。
  2. 无匹配时的rowStyle逻辑异常:当搜索/过滤无结果时,state.pageRows为空数组,此时访问prevRow['Petal.Length']会触发错误,导致表格渲染失败。

解决方案

针对上述两个问题,分别修改代码:

  1. 添加正则特殊字符转义函数,避免构造RegExp时出错;
  2. 在rowStyle中增加对state.pageRows是否为空的判断,同时确保prevRow存在时再访问其属性。

修改后的完整代码:

library(reactable)
library(htmltools)

# 新增正则特殊字符转义函数
escapeRegExp <- JS('function(str) {
  return str.replace(/[.*+?^${}()|[\]\\\\]/g, "\\\\$&");
}')

customsearch <-  JS('
function(rows, columnIds, filterValue) {
    let arrFilterValues = filterValue.split(" ").filter(e => e.trim() !== ""); // 过滤空字符串

    // 无搜索值时直接返回所有行
    if (arrFilterValues.length === 0) return rows;

    return rows.filter(function(row) {
        return arrFilterValues.map(function(e) {
            const escapedVal = escapeRegExp(e);
            return columnIds.some(function(columnId) {
                return new RegExp(escapedVal,"i").test(row.values[columnId])
            });
        }).every(v => v === true);
    });
}')

customfilter <- JS('function(rows, columnId, filterValue) {
    let arrFilterValues = filterValue.split(" ").filter(e => e.trim() !== "");

    if (arrFilterValues.length === 0) return rows;

    return rows.filter(function(row) {
        return arrFilterValues.map(function(e) {
                const escapedVal = escapeRegExp(e);
                return new RegExp(escapedVal,"i").test(row.values[columnId])
        }).every(v => v === true);
    });
}')


reactable(iris,filterable=TRUE,searchable=TRUE,static=TRUE, rowStyle=JS("function(rowInfo, state) {
    // 无数据时直接返回,避免报错
    if (!state.pageRows || state.pageRows.length === 0) return;
    
    const firstSorted = state.sorted[0]
    if (!firstSorted || firstSorted.id === 'Petal.Length') {
      const prevRow = state.pageRows[rowInfo.viewIndex - 1]
      // 确保prevRow存在且对应属性相等时才折叠
      if (prevRow && rowInfo.values['Petal.Length'] === prevRow['Petal.Length']) {
        return { visibility: 'collapse' }
      }
    }
  }"), searchMethod = customsearch, defaultColDef=colDef(filterMethod=customfilter, html=TRUE))

关键修改说明

  • 正则转义:新增escapeRegExp函数,对输入的搜索字符中的正则元字符进行转义,确保RegExp构造函数能正常解析;
  • 空值处理:在搜索/过滤函数中,先过滤掉拆分后的空字符串,无有效搜索值时直接返回所有行;
  • rowStyle容错:增加对state.pageRows是否为空的判断,避免无数据时执行后续逻辑引发错误。

内容的提问来源于stack exchange,提问作者userq8957289475

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:05:18