read - saber si un objeto esta vacio javascript
Reaccionar: TypeError no capturado: no se puede leer la propiedad ''setState'' de undefined (17)
- Verificar estado verificar estado si creas una propiedad particular o no
this.delta = this.delta.bind(this);
2. Verifique (esto) si está haciendo setState dentro de cualquier función (es decir, handleChange) verifique si la función se une a esto o si la función debería ser una función de flecha.
## 3 formas de vincular esto a la siguiente función ##
this.delta.bind(this);
Estoy teniendo el siguiente error
TypeError no capturado: no se puede leer la propiedad ''setState'' de undefined
incluso después de enlazar delta en el constructor.
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>
);
}
}
Agregando
onClick = {this.delta.bind (this)}
Resolverá el problema. Este error se produce cuando intentamos llamar a la función de la clase ES6, por lo que debemos vincular el método.
Aunque esta pregunta ya tenía una solución, solo quiero compartir la mía para aclararla, espero que pueda ayudar:
delta = () => {
this.setState({
count : this.state.count++
});
}
Cuando use el código ES6 en React, siempre use las funciones de flecha, porque este contexto se vincula automáticamente con él
Utilizar esta:
(videos) => {
this.setState({ videos: videos });
console.log(this.state.videos);
};
en vez de:
function(videos) {
this.setState({ videos: videos });
console.log(this.state.videos);
};
Debe vincular esto al constructor y recordar que los cambios en el constructor deben reiniciar el servidor. O bien, terminará con el mismo error.
Debe vincular sus métodos con ''this'' (objeto predeterminado). Entonces, cualquiera que sea su función, solo agréguela al constructor.
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>
);
En
ES7 +
(ES2016) puede usar la
función
experimental
bind syntax
operator
::
to bind.
Es un azúcar sintáctico y hará lo mismo que la respuesta de Davin Tryon.
Luego puede reescribir
this.delta = this.delta.bind(this);
a
this.delta = ::this.delta;
Para
ES6 +
(ES2015) también puede usar la
función de flecha
ES6 + (
=>
) para poder usar
this
.
delta = () => {
this.setState({
count : this.state.count + 1
});
}
Por qué ? Del documento de Mozilla:
Hasta que la flecha funciona, cada nueva función define su propio valor [...]. Esto resultó ser molesto con un estilo de programación orientado a objetos.
Las funciones de flecha capturan el valor de este del contexto [...]
Este error puede resolverse por varios métodos:
-
Si está utilizando la sintaxis de ES5 , entonces, según la documentación de React js , debe utilizar el método de enlace .
Algo como esto para el ejemplo anterior:
this.delta = this.delta.bind(this)
-
Si está utilizando la sintaxis de ES6 , entonces no necesita utilizar el método de enlace , puede hacerlo con algo como esto:
delta=()=>{ this.setState({ count : this.state.count++ }); }
Esto se debe a que
this.delta
no está vinculado a
this
.
Para enlazar, configure
this.delta = this.delta.bind(this)
en el constructor:
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = this.delta.bind(this);
}
Actualmente, estás llamando a Bind. Pero bind devuelve una función enlazada. Debe establecer la función en su valor límite.
Hay dos soluciones a este problema:
La primera solución es agregar un constructor a su componente y vincular su función como se muestra a continuación:
/*
* 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() {
//....
}
}
Entonces haz esto:
<!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>
En lugar de esto:
this.state = {
name: "",
email: ""
}
this.setState(() => ({
comments: comments //comments not available in state
}))
La segunda solución es usar una función de flecha en su lugar:
//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)
}
En realidad, la función de flecha
NO se
vincula a
this
.
Las funciones de flecha
bind
léxicamente su contexto, por
this
realidad se refiere al
contexto de origen
.
Para más información sobre la función de enlace:
Función de vinculación Comprensión de JavaScript Bind ()
Para más información sobre la función de flecha:
Hay una diferencia de contexto entre las clases ES5 y ES6. Por lo tanto, también habrá una pequeña diferencia entre las implementaciones.
Aquí está la versión 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>
);
}
});
y aquí está la versión 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>
);
}
}
Solo tenga cuidado, además de la diferencia de sintaxis en la implementación de la clase, hay una diferencia en el enlace del controlador de eventos.
En la versión ES5, es
<button onClick={this.delta}>+</button>
En la versión ES6, es:
<button onClick={this.delta.bind(this)}>+</button>
La función de flecha podría haber hecho su vida más fácil para evitar vincular esta palabra clave. Al igual que:
delta = () => {
this.setState({
count : this.state.count++
});
}
No tiene que vincular nada, solo use las funciones de flecha como esta:
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>
);
}
}
Simplemente cambie su declaración de enlace de lo que tiene que => this.delta = this.delta.bind (this);
También puedes usar:
<button onClick={()=>this.delta()}>+</button>
O:
<button onClick={event=>this.delta(event)}>+</button>
Si estás pasando algunos params ...
tienes que vincular un nuevo evento con esta palabra clave como menciono a continuación ...
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>
);
}
}
constructor(props) {
super(props);
...
this.delta = this.delta.bind(this);
}