Je reçois l'erreur suivante
Uncaught TypeError: Impossible de lire la propriété 'setState' de non définie
même après la liaison delta dans le constructeur.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
Ceci est dû au fait que this.delta
n'est pas lié à this
.
Afin de lier set this.delta = this.delta.bind(this)
dans le constructeur:
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = this.delta.bind(this);
}
Actuellement, vous appelez bind. Mais bind renvoie une fonction liée. Vous devez définir la fonction sur sa valeur liée.
Dans ES7 + (ES2016), vous pouvez utiliser la syntaxe de liaison expérimentale function operator ::
pour lier. C'est un sucre syntaxique qui fera la même chose que la réponse de Davin Tryon.
Vous pouvez ensuite réécrire this.delta = this.delta.bind(this);
en this.delta = ::this.delta;
Pour ES6 + (ES2015), vous pouvez également utiliser la fonction de flèche ES6 + (=>
) pour pouvoir utiliser this
.
delta = () => {
this.setState({
count : this.state.count + 1
});
}
Pourquoi ? De la doc de Mozilla:
Jusqu'à ce que la flèche fonctionne, chaque nouvelle fonction définit sa propre valeur this _ [...]. Cela s'est avéré ennuyeux avec un style de programmation orienté objet.
Les fonctions de flèche capturent la valeur this _ du contexte englobant [...]
Il y a une différence de contexte entre les classes ES5 et ES6. Donc, il y aura aussi une petite différence entre les implémentations.
Voici la version ES5:
var Counter = React.createClass({
getInitialState: function() { return { count : 1 }; },
delta: function() {
this.setState({
count : this.state.count++
});
},
render: function() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
});
et voici la version ES6:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count : 1 };
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta.bind(this)}>+</button>
</div>
);
}
}
Attention, à côté de la différence de syntaxe dans l'implémentation de la classe, il existe une différence dans la liaison du gestionnaire d'événements.
Dans la version ES5, c'est
<button onClick={this.delta}>+</button>
Dans la version ES6, c'est:
<button onClick={this.delta.bind(this)}>+</button>
Lorsque vous utilisez du code ES6 dans React, utilisez toujours les fonctions de flèche, car le contexte this est automatiquement lié
Utilisez ceci:
(videos) => {
this.setState({ videos: videos });
console.log(this.state.videos);
};
au lieu de:
function(videos) {
this.setState({ videos: videos });
console.log(this.state.videos);
};
Vous ne devez rien lier, utilisez simplement les fonctions de flèche comme ceci:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 1
};
}
//ARROW FUNCTION
delta = () => {
this.setState({
count: this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
Vous pouvez aussi utiliser:
<button onClick={()=>this.delta()}>+</button>
Ou:
<button onClick={event=>this.delta(event)}>+</button>
Si vous passez quelques paramètres ..
Vous devez lier vos méthodes avec 'this' (objet par défaut) . Ainsi, quelle que soit votre fonction, vous pouvez simplement lier cela au constructeur.
constructor(props) {
super(props);
this.state = { checked:false };
this.handleChecked = this.handleChecked.bind(this);
}
handleChecked(){
this.setState({
checked: !(this.state.checked)
})
}
render(){
var msg;
if(this.state.checked){
msg = 'checked'
}
else{
msg = 'not checked'
}
return (
<div>
<input type='checkbox' defaultChecked = {this.state.checked} onChange = {this.handleChecked} />
<h3>This is {msg}</h3>
</div>
);
Vous devez associer ceci au constructeur et vous rappeler que les modifications apportées au constructeur nécessitent le redémarrage du serveur. Sinon, vous allez finir avec la même erreur.
vous devez lier un nouvel événement avec this mot-clé comme je le mentionne ci-dessous ...
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
Il existe deux solutions à ce problème:
La première solution consiste à ajouter un constructeur à votre composant et à lier votre fonction comme ci-dessous:
constructor(props) {
super(props);
...
this.delta = this.delta.bind(this);
}
Alors faites ceci:
this.delta = this.delta.bind(this);
Au lieu de cela:
this.delta.bind(this);
La deuxième solution consiste à utiliser une fonction flèche à la place:
delta = () => {
this.setState({
count : this.state.count++
});
}
En fait, la fonction flèche NE LIE PAS elle-même this
. Les fonctions fléchées lexicalement bind
leur contexte donc this
fait en réalité référence au contexte d'origine .
Pour plus d'informations sur la fonction bind:
Fonction BindComprendre JavaScript Bind ()
Pour plus d'informations sur la fonction flèche:
Cette erreur peut être résolue par différentes méthodes.
Si vous utilisez ES5 syntaxe, conformément à React js Documentation , vous devez utiliser bind méthode.
Quelque chose comme ça pour l'exemple ci-dessus:
this.delta = this.delta.bind(this)
Si vous utilisez la syntaxe ES6 , vous n'avez pas besoin d'utiliser la méthode bind , vous pouvez le faire avec quelque chose comme ceci:
delta=()=>{ this.setState({ count : this.state.count++ }); }
La fonction de flèche pourrait vous rendre la vie plus facile pour éviter la liaison this mot-clé. Ainsi:
delta = () => {
this.setState({
count : this.state.count++
});
}
this.state = {
name: "",
email: ""
}
this.setState(() => ({
comments: comments //comments not available in state
}))
2 .Cochez la case (this) si vous effectuez setState dans une fonction (par exemple, handleChange), vérifiez si la fonction est liée à cette fonction ou à la fonction flèche.
## 3 façons de lier ceci à la fonction ci-dessous ##
//3 ways for binding this to the below function
handleNameChange(e) {
this.setState(() => ({ name }))
}
// 1.Bind while callling function
onChange={this.handleNameChange.bind(this)}
//2.make it as arrow function
handleNameChange((e)=> {
this.setState(() => ({ name }))
})
//3.Bind in constuctor
constructor(props) {
super(props)
this.state = {
name: "",
email: ""
}
this.handleNameChange = this.handleNameChange.bind(this)
}
bien que cette question ait déjà une solution, je veux juste partager le mien pour la clarifier, espérons que cela puisse aider:
/*
* The root cause is method doesn't in the App's context
* so that it can't access other attributes of "this".
* Below are few ways to define App's method property
*/
class App extends React.Component {
constructor() {
this.sayHi = 'hello';
// create method inside constructor, context = this
this.method = ()=> { console.log(this.sayHi) };
// bind method1 in constructor into context 'this'
this.method1 = this.method.bind(this)
}
// method1 was defined here
method1() {
console.log(this.sayHi);
}
// create method property by arrow function. I recommend this.
method2 = () => {
console.log(this.sayHi);
}
render() {
//....
}
}
Il suffit de changer votre instruction bind de ce que vous devez => this.delta = this.delta.bind (this);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/[email protected]/dist/react.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props);
this.state = {
counter : 0,
isToggle: false
}
this.onEventHandler = this.onEventHandler.bind(this);
}
increment = ()=>{
this.setState({counter:this.state.counter + 1});
}
decrement= ()=>{
if(this.state.counter > 0 ){
this.setState({counter:this.state.counter - 1});
}else{
this.setState({counter:0});
}
}
// Either do it as onEventHandler = () => {} with binding with this // object.
onEventHandler(){
this.setState({isToggle:!this.state.isToggle})
alert('Hello');
}
render(){
return(
<div>
<button onClick={this.increment}> Increment </button>
<button onClick={this.decrement}> Decrement </button>
{this.state.counter}
<button onClick={this.onEventHandler}> {this.state.isToggle ? 'Hi':'Ajay'} </button>
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root'),
);
</script>
</body>
</html>
Ajouter
onClick = {this.delta.bind (this)}
résoudra le problème . cette erreur survient lorsque nous essayons d'appeler la fonction de la classe ES6, Nous devons donc lier la méthode.