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) }
3 Réponses :
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())
@epascarello a également ajouté null, mais j'espère que c'est assez clair d'après les exemples ci-dessus
Juste au cas où vos valeurs d'objet ne seraient pas définies:
(item.companyName||'').toLowerCase().indexOf(keyword)
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 .
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']
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.