Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS Cannot read property setState of undefined [duplicate]

I am new to ReactJS, and somewhat understand that this question is duplicated to numeral questions in SOF.

But I hope someone can give me some directions and clarifications on some concepts of React.

What I want to do is simply get data from remote REST API using axios or isomorphic-fetch before the screen is loaded.

However, I saw quite a lot of similar React tutorials, I still did not get the point.

Here is my code:

import React, { Component } from 'react';
import axios from 'axios'

// import InputRow from './components/InputRow';
import './App.css';

// require('es6-promise').polyfill();
// require('isomorphic-fetch');

class App extends Component {

	constructor(props) {
		super(props);

		const app_id = '<my_app_id>';

		const version = 0.1;
		this.luisURL = `https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/${app_id}/versions/${version}`;

		// this.getLUISIntent = this.getLUISIntent.bind(this);

		this.state = {
			intentOptions: [],
			utterance: '',
			intent: ''
		};
	}

	getLUISIntent = () => {
		const subscription_key = '<my_subscription_key>';

		const URL = this.luisURL + '/intents';

		return axios.get(URL, {
			headers: {
				"Content-Type": 'application/json',
				"Ocp-Apim-Subscription-Key": subscription_key
			},
		})
		.then(function(res){
			this.setState({intentOptions: res.data});
		});
	}

	componentWillMount = () => {
		// this.setState({
		// 	intentOptions: this.getLUISIntent()
		// });
	}

	componentDidMount = () => {
		this.getLUISIntent();
	}

	componentDidUpdate = (prevProps, prevState) => {
		console.log("state: ", this.state);
		// this.submitToLUIS();
	}

	shouldComponentUpdate = (nextProps, nextState) => {
		return true;
	}

	submitToLUIS = () => {
		console.log("Submit to LUIS: ", this.state);
	};

	setIntent = (e) => {
		this.setState({intent: e.target.value});
	};

	setUtterance = (e) => {
		this.setState({utterance: e.target.value});
	};

	render() {
		return (
			<div className="App">
				<div className="container">
					<div className="row">
						<div className="col-sm-4">Utterance</div>
						<div className="col-sm-4">Intent</div>
						<div className="col-sm-4"></div>
					</div>
					<div className="row">
						<div className="col-sm-4">
							<input className="form-control utterance" type="text" onChange={this.setUtterance} />
						</div>
						<div className="col-sm-4">
							<select className="form-control intent" onChange={this.setIntent}>
								<option key="intent_defualt" value="">Select...</option>
								{this.state.intentOptions.map((obj, i) =>
									<option key={obj.id} value={obj.id}>{obj.name}</option>
								)}
							</select>
						</div>
						<div className="col-sm-4">
							<button className="btn btn-primary" onClick={this.submitToLUIS}>Create</button>
						</div>
					</div>
				</div>
      		</div>
    	);
  	}
}

export default App;

Here are my questions:

  • I want to load the list before showing the whole UI, what is missing in this code?
  • Is it correct here to use arrow function in getLUISIntent?
  • Can I use async/await in getLUISIntent()?
  • To me, async/await means waiting for the response from function before executing the next "line". Is this concept correct?
  • If I need to write an additional this.__my_fancy_function__ = this.__my_fancy_function__.bind(this) to use a class function, using arrow function seems writes less code and more readable, why not everyone use it?
  • Are there any Fetch remote API before loading anything using ReactJS tutorial no splitting different component but showing everything in only single App.js No BS so that everyone can see how a REST API-simple ReactJS app is run tutorial out there? If there is no such thing I would like to write it. But before that I hope someone can help clear my thought first.

Thank you very much in advance for your kind help.

like image 824
Ellery Leung Avatar asked Apr 01 '18 16:04

Ellery Leung


People also ask

How to solve TypeError cannot read property'setState'of undefined ReactJS?

TypeError: Cannot read property 'setState' of undefined ReactJS The solution. The issue happens because the method is not properly bind with this. As we all know that when we create a function it has it’s own special object this. As the arrow function does not have any special object this. This problem can be solved with the arrow function ...

How to fix “this setState is not a function” error in react?

Use the ES6 syntax for the big arrow function. It automatically binds the “this” keyword to that method so you don’t have to bind it in the constructor: There you have it! That’s how you get rid of the “this.setState” is “undefined” or “not a function” error when using the class component structure in React.

Why arrow function is not working in ReactJS?

The issue happens because the method is not properly bind with this. As we all know that when we create a function it has it’s own special object this. As the arrow function does not have any special object this. This problem can be solved with the arrow function like below: Here is a good article about bind of ReactJS component classes.

Why am I getting errors when calling a method in react?

These errors occur because the method you are using or invoking in your React Component is not bound correctly. Here is an example of code that will cause the error to happen (This assumes that you have your React component set up correctly):


1 Answers

your callback function from the ajax request is not bound. When you pass a function to another function (as a callback), "this" will be a reference to the context it is in when it is finally called, as opposed to what it is when you wrote it. If you use an arrow function, it will keep the context it had when you wrote it.

.then(function(res){
        this.setState({intentOptions: res.data});
    });

If you make this function an arrow function, the issue should be resolved.

.then((res) => this.setState({intentOptions: res.data}));
like image 181
Jason Spradlin Avatar answered Nov 01 '22 10:11

Jason Spradlin