J'apprends ReactJS et suis coincé avec le problème suivant. J'ai une entrée pour la recherche de contacts et je veux la gérer en 1000 ms après l'arrêt de la frappe d'un utilisateur. J'utilise la fonction anti-rebond à cette fin:
import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {debounce} from 'lodash';
const contacts = [
{
id: 1,
name: 'Darth Vader',
phoneNumber: '+250966666666',
image: 'img/darth.gif'
}, {
id: 2,
name: 'Princess Leia',
phoneNumber: '+250966344466',
image: 'img/leia.gif'
}, {
id: 3,
name: 'Luke Skywalker',
phoneNumber: '+250976654433',
image: 'img/luke.gif'
}, {
id: 4,
name: 'Chewbacca',
phoneNumber: '+250456784935',
image: 'img/chewbacca.gif'
}
];
class Contact extends React.Component {
render() {
return (
<li className="contact">
<img className="contact-image" src={this.props.image} width="60px" height="60px"/>
<div className="contact-info">
<div className="contact-name">{this.props.name}</div>
<div className="contact-number">{this.props.phoneNumber}</div>
</div>
</li>
);
}
}
class ContactList extends React.Component {
constructor(props) {
super(props);
this.state = {
displayedContacts: contacts,
};
this.handleChange = debounce(this.handleChange.bind(this), 1000);
}
handleChange = e => {
e.persist();
let input = e.target.value.toLowerCase();
this.setState({
displayedContacts: contacts.filter(c => c.name.toLowerCase().includes(input))
});
}
render() {
return (
<div className="contacts">
<input type="text" className="search-field" onChange={this.handleChange}/>
<ul className="contacts-list">
{
this.state.displayedContacts.map(c =>
<Contact
key={c.id}
name={c.name}
phoneNumber={c.phoneNumber}
image={c.image} />
)
}
</ul>
</div>
);
}
}
ReactDOM.render(
<ContactList />,
document.getElementById('root')
);
Dans le journal de la console après avoir rempli l'entrée de recherche, j'obtiens un avertissement "Cet événement synthétique est réutilisé pour des raisons de performances. Si vous voyez cela, vous accédez à la propriété target
sur un événement synthétique libéré/annulé. Il est défini sur null. Si vous devez conserver l'événement synthétique d'origine, utilisez event.persist () "
et une erreur "TypeError non intercepté: impossible de lire la propriété 'value' de null à ContactList._this2.handleChange".
J'utilise la méthode persist
dans la fonction handleChange
. Pourquoi je reçois cette erreur?
Les gestionnaires d'événements sont mieux exécutés de manière synchrone. Vous pouvez gérer le value
séparément et filtrer les contacts dans une fonction anti-rebond distincte.
Exemple
class ContactList extends React.Component {
state = {
contacts,
displayedContacts: contacts
};
setDisplayedContacts = debounce(query => {
this.setState({
displayedContacts: this.state.contacts.filter(c =>
c.name.toLowerCase().includes(query)
)
});
}, 1000);
handleChange = e => {
let input = e.target.value.toLowerCase();
this.setDisplayedContacts(input);
};
render() {
return (
<div className="contacts">
<input
type="text"
className="search-field"
onChange={this.handleChange}
/>
<ul className="contacts-list">
{this.state.displayedContacts.map(c => (
<Contact
key={c.id}
name={c.name}
phoneNumber={c.phoneNumber}
image={c.image}
/>
))}
</ul>
</div>
);
}
}