subproperty single react property array javascript reactjs

javascript - single - setstate array react



Reaccionar this.setState no es una funciĆ³n (10)

Soy nuevo en React y estoy tratando de escribir una aplicación que funcione con una API. Sigo recibiendo este error:

TypeError: this.setState no es una función

cuando trato de manejar la respuesta API. Sospecho que hay algo mal con este enlace, pero no puedo encontrar la manera de solucionarlo. Aquí está el código de mi componente:

var AppMain = React.createClass({ getInitialState: function() { return{ FirstName: " " }; }, componentDidMount:function(){ VK.init(function(){ console.info("API initialisation successful"); VK.api(''users.get'',{fields: ''photo_50''},function(data){ if(data.response){ this.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(this.state.FirstName); } }); }, function(){ console.info("API initialisation failed"); }, ''5.34''); }, render:function(){ return ( <div className="appMain"> <Header /> </div> ); } });


Ahora ES6 tiene función de flecha, es realmente útil si realmente confundes con la expresión bind (this) puedes probar la función de flecha

Así es como lo hago.

componentWillMount() { ListApi.getList() .then(JsonList => this.setState({ List: JsonList })); } //Above method equalent to this... componentWillMount() { ListApi.getList() .then(function (JsonList) { this.setState({ List: JsonList }); }.bind(this)); }


Ahora, en reaccionar con es6 / 7, puede vincular la función al contexto actual con la función de flecha como esta, hacer una solicitud y resolver promesas como esta:

listMovies = async () => { const request = await VK.api(''users.get'',{fields: ''photo_50''}); const data = await request.json() if (data) { this.setState({movies: data}) } }

Con este método, puede llamar fácilmente a esta función en el componenteDidMount y esperar los datos antes de representar su html en su función de representación.

No sé el tamaño de su proyecto, pero personalmente desaconsejo usar el estado actual del componente para manipular datos. Debe usar un estado externo como Redux o Flux o algo más para eso.


Aquí ESTE contexto está cambiando. Use la función de flecha para mantener el contexto de la clase React.

VK.init(() => { console.info("API initialisation successful"); VK.api(''users.get'',{fields: ''photo_50''},(data) => { if(data.response){ this.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(this.state.FirstName); } }); }, function(){ console.info("API initialisation failed"); }, ''5.34'');


La devolución de llamada se realiza en un contexto diferente. Debe bind a this para tener acceso dentro de la devolución de llamada:

VK.api(''users.get'',{fields: ''photo_50''},function(data){ if(data.response){ this.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(this.state.FirstName); } }.bind(this));

EDITAR: Parece que tienes que vincular las llamadas init y api :

VK.init(function(){ console.info("API initialisation successful"); VK.api(''users.get'',{fields: ''photo_50''},function(data){ if(data.response){ this.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(this.state.FirstName); } }.bind(this)); }.bind(this), function(){ console.info("API initialisation failed"); }, ''5.34'');


No es necesario asignar esto a una variable local si utiliza la función de flecha. Las funciones de flecha se vinculan automáticamente y puede mantenerse alejado de los problemas relacionados con el alcance.

El siguiente código explica cómo usar la función de flecha en diferentes escenarios

componentDidMount = () => { VK.init(() => { console.info("API initialisation successful"); VK.api(''users.get'',{fields: ''photo_50''},(data) => { if(data.response){ that.setState({ //this available here and you can do setState FirstName: data.response[0].first_name }); console.info(that.state.FirstName); } }); }, () => { console.info("API initialisation failed"); }, ''5.34''); },


Puede evitar la necesidad de .bind (esto) con una función de flecha ES6.

VK.api(''users.get'',{fields: ''photo_50''},(data) => { if(data.response){ this.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(this.state.FirstName); } });


React recomienda vincular esto en todos los métodos que necesitan usar esto de class lugar de esto de auto function .

constructor(props) { super(props) this.onClick = this.onClick.bind(this) } onClick () { this.setState({...}) }

O puede usar la arrow function lugar.


Si está haciendo esto y todavía tiene un problema, mi problema es que estaba llamando a dos variables con el mismo nombre.

Tenía companies como un objeto traído de Firebase, y luego estaba tratando de llamar a this.setState({companies: companies}) , no estaba funcionando por razones obvias.


Solo necesitas vincular tu evento

por ex

// place this code to your constructor this._handleDelete = this._handleDelete.bind(this); // and your setState function will work perfectly _handleDelete(id){ this.state.list.splice(id, 1); this.setState({ list: this.state.list }); // this.setState({list: list}); }


También puede guardar una referencia a this antes de invocar el método api :

componentDidMount:function(){ var that = this; VK.init(function(){ console.info("API initialisation successful"); VK.api(''users.get'',{fields: ''photo_50''},function(data){ if(data.response){ that.setState({ //the error happens here FirstName: data.response[0].first_name }); console.info(that.state.FirstName); } }); }, function(){ console.info("API initialisation failed"); }, ''5.34''); },