开发者问题收集

ReactJS 错误:TypeError:无法读取 null 的属性“toLowerCase”

2019-04-05
12285

我正在使用 reactjs 中的搜索过滤器,目前在第一次或第二次尝试时,当用户输入值时,它工作正常,但是当用户在第三次尝试时输入一些文本时,它会产生错误 TypeError: 无法读取 null 的属性“toLowerCase” 。我将提供逻辑作为代码,有人可以帮我解决这个问题吗?我是 ReactJS 的新手,没有太多知识来解决这个问题。

代码

    searchHandler(event) {
    let keyword = event.target.value;
    clearTimeout(this.typingTimer);
    this.typingTimer=setTimeout(()=>{
      let filter= {

        "where": {
          "or": [
            {
              "companyName":{"regexp":keyword +"/i"}
            },
            {
              "primaryPhone":{"regexp":keyword +"/i"}
            },
            {
              "emailAddress":{"regexp":keyword +"/i"}
            },
            {
              "venueCode":{"regexp":keyword +"/i"}
            },
            {
              "website":{"regexp":keyword +"/i"}
            },
          ]
        }
      }

      this.props.getParties(filter);
      let filtered = this.state.data.filter(item => {
        return (
          item.companyName.toLowerCase().indexOf(keyword) > -1 ||
          item.primaryPhone.toLowerCase().indexOf(keyword) > -1 ||
          item.emailAddress.toLowerCase().indexOf(keyword) > -1 ||
          item.venueCode.toLowerCase().indexOf(keyword) > -1 ||
          item.website.toLowerCase().indexOf(keyword) > -1 ||
          item.description.toLowerCase().indexOf(keyword) > -1
        );
      });

      if (keyword === "") {
        filtered = [];
        this.getData();
      }

      this.setState({
        filtered,
      });
      const { skip } = this.state;
      if(this.state.filtered.length>0 || !this.state.filtered.length){
        this.setState({
          filtered:[],
          skip: skip - skipDecrement
        })
      }
    },550)

  }
3个回答

您遇到的问题是,无论设置数据什么,都会将属性设置为 null。因此,当您检查它时,它会引发错误。

您可以使代码复杂化,并在执行之前检查它是否真实。

(item.companyName && item.companyName.toLowerCase().indexOf(keyword) > -1) ||
(item.primaryPhone && item.primaryPhone.toLowerCase().indexOf(keyword) > -1) ||

我个人不会这样做,我会使用 someincludes

定义要检查的字段数组

const fields = ['companyName','primaryPhone','emailAddress','venueCode','website','description']

在您的过滤器代码中,使用 some 并循环查看它们是否真实并且是否匹配

let filtered = keyword.length
  ? this.state.data.filter(item =>
      fields.some(prop =>
        item[prop] && item[prop].toLowerCase().includes(keyword)
      )
    )
  : []

您的代码的下一个问题是这个

if(this.state.filtered.length>0 || !this.state.filtered.length)

第一个语句表示是否大于零,第二个语句表示是否为零。所以不确定你期望发生什么。

你遇到的下一个问题是你正在读取 this.state.filtered。问题是你在上面用 this.setState(....) 设置了它。问题是 setState 是异步的,所以你检查的值不会在那里。你有变量 filtered 所以使用它。

if (!filtered.length)
epascarello
2019-04-05

以防万一您的对象值未设置:

(item.companyName||'').toLowerCase().indexOf(keyword)
Miroslav Glamuzina
2019-04-05

您需要在调用 toLowerCase 之前添加检查,因为这仅适用于字符串

let a  = ''
let b = undefined
let c = [1,2,3]
let d = null
let e = 'HELLO'

typeof a === 'string' && a && console.log(a.toLowerCase())
typeof b === 'string' && b && console.log(b.toLowerCase())
typeof c === 'string' && c && console.log( c.toLowerCase())
typeof d === 'string' && d && console.log( d.toLowerCase())
typeof e === 'string' && e && console.log( e.toLowerCase())
Code Maniac
2019-04-05