2
votes

Erreur ReactJS: TypeError: impossible de lire la propriété 'toLowerCase' de null

Je travaille sur le filtre de recherche dans reactjs, actuellement à la première ou à la deuxième tentative lorsque l'utilisateur saisit la valeur, cela fonctionne bien, mais lorsque l'utilisateur saisit du texte à la troisième tentative, cela génère l'erreur TypeError: Cannot read property 'toLowerCase 'de null . Je vais me fournir une logique comme un code pourrait quelqu'un s'il vous plaît m'aider à résoudre ce problème. Je suis nouveau sur ReactJS et je n'ai pas beaucoup de connaissances pour résoudre ce problème.

Code

    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)

  }


4 commentaires

signifie que l'un des éléments XYZ est nul


Oui, je ne sais pas pourquoi il apparaît comme nul.


enfin, quel que soit le réglage, il met null dedans ....


Veuillez ne pas modifier le code de votre question afin qu'il invalide les réponses. De plus, ne postez pas de duplicata de votre question.


3 Réponses :


1
votes

Vous devez ajouter une vérification avant d'appeler toLowerCase car elle n'est disponible que sur la chaîne

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())


1 commentaires

@epascarello a également ajouté null, mais j'espère que c'est assez clair d'après les exemples ci-dessus



2
votes

Juste au cas où vos valeurs d'objet ne seraient pas définies:

(item.companyName||'').toLowerCase().indexOf(keyword)


15 commentaires

Eh bien, l'erreur a disparu mais cette expression ne fonctionne pas. pouvez-vous vérifier si (this.state.filtered.length> 0 ||! this.state.filtered.length) {this.setState ({filtered: [], skip: skip - skipDecrement})}


désolé, je ne vous comprends pas?


Si vous me fournissez un extrait de code plus complet, je pourrai peut-être vous aider :)


Pouvons-nous faire une session Teamviewer pendant 10 minutes? si possible


Pouvez-vous fournir un violon, vous pouvez utiliser un site comme jsfiddle.net et partager un lien ici dans votre question


Je ne peux pas être certain (car il n'est pas en cours d'exécution), mais si vous n'en étiez pas conscient, this.setState () est asynchrone, cela signifie que même si vous définissez filtré avec setState () au-dessus de if (this.state.filtered.length> 0 ... , cela ne signifie pas nécessairement que la valeur de this.state.filtered a encore été mis à jour. * Si vous avez besoin de la valeur mise à jour tout de suite: * utilisez le deuxième paramètre de this.setState ({filtered}, updatedState => {if (updatedState. filtered.length) {...}}) . Cela devrait donner les résultats que vous attendez


Veuillez consulter medium.com/@wereHamster/… pour un aperçu


@MiroslavGlamuzina ou comme ce qui a été dit dans ma réponse , il n'est pas nécessaire d'utiliser le callback car ils ont déjà la valeur .... Mais en réalité, setState semble être appelé trop de fois et pourrait être refactorisé pour être appelé juste une fois.


J'ai essayé mais ne fonctionne pas pour moi, pourriez-vous s'il vous plaît l'écrire via jsfiddle.net


Comme l'a dit @epascarello, vous avez déjà la valeur, il existe une meilleure façon d'écrire cela. Je mettrai à jour ma réponse sous peu afin que vous puissiez voir comment écrire ceci :)


Vous devrez examiner de plus près quand mettre à jour votre état, il semble que vous mettez inutilement à jour filtré et que vous annulez la valeur par la suite. Je ne sais pas ce que vous aimeriez en faire. Mais en ce qui concerne la configuration de votre variable filtrée , quelque chose comme ça suffira ... désolé pour le formatage:


let filtered = []; if (keyword! == "") {/ * La mutation des accessoires / état est tabou dans React. Vous étiez en mutation d'état ici, en faisant [... x] vous pouvez créer une nouvelle instance de array * / filtered = [... this.state.data] .filter (item => ((item.companyName || '') .toLowerCase (). indexOf (keyword)> -1 || (item.primaryPhone | | '') .toLowerCase (). indexOf (mot-clé)> -1 || (item.emailAddress || '') .toLowerCase (). indexOf (mot-clé)> -1 || (item.venueCode || '') .toLowerCase (). indexOf (mot-clé)> -1 || (item.website || '') .toLowerCase (). indexOf (mot-clé)> -1 || (item.description || '') .toLowerCase () .indexOf (mot-clé)> -1));}


C'est le mieux que je puisse faire sans donc plus de questions, si vous avez d'autres questions, n'hésitez pas à poster une nouvelle question :)


@MiroslavGlamuzina, en fait, je ne suis pas défini les valeurs filtrées après que l'utilisateur effectue une recherche, si vous voyez skip: skip - skipDecrement cela met à jour l'état mais quand j'essaye avec skip: 0 il ne met pas à jour mon état. Si l'état de skip: 0 est mis à jour correctement, cela résoudra mon problème


continuons cette discussion dans le chat .



2
votes

Le problème que vous rencontrez est que tout ce qui définit les données définit les propriétés sur null. Ainsi, lorsque vous le vérifiez, cela génère une erreur.

Vous pouvez compliquer votre code et vérifier s'il est véridique avant de le faire.

if (!filtered.length)

Personnellement, je ne ferais pas cela et j'utiliserais certains et inclut.

Définissez un tableau des champs à vérifier

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

Et dans votre code de filtre, Utilisez-en quelques-uns et faites une boucle pour voir s'ils sont véridiques et qu'ils correspondent

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

Le prochain problème avec votre code est le suivant

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


0 commentaires