Reputation: 3545
I am making a simple AJAX request with the fetch API in React, specifically in the componentDidMount()
function.
It is working, because the console appears to be logging the result. However, I don't know how to access the response...
componentDidMount = () => {
let URL = 'https://jsonplaceholder.typicode.com/users'
fetch(URL)
.then(function(response) {
let myData = response.json()
return myData;
})
.then(function(json) {
console.log('parsed json', json)
})
.catch(function(ex) {
console.log('parsing failed', ex)
})
} // end componentDidMount
I tried accessing myData
outside of the fetch method, but this throws an error saying that it is undefined. So it is only accessible within the scope of the function.
I then tried this:
.then(function(response) {
let myData = response.json()
// return myData;
this.setState({
data: myData
})
})
This time, I get Cannot read property 'setState' of undefined(…)
How do I pass the fetch response to the state, or even just a global variable?
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: null
}
}
componentDidMount() {
let URL = 'https://jsonplaceholder.typicode.com/users'
fetch(URL)
.then( (response) => {
let myData = response.json()
// return myData;
this.setState({
data: myData
})
})
.then( (json) => {
console.log('parsed json', json)
})
.catch( (ex) => {
console.log('parsing failed', ex)
})
console.log(this.state.data)
} // end componentDidMount
render() {
return (
<div className="App">
{this.state.data}
</div>
);
}
}
export default App;
Upvotes: 6
Views: 19557
Reputation: 924
Change the way you access the response data by using '=>' instead of function to be in the same context.
componentDidMount = () => {
let URL = 'https://jsonplaceholder.typicode.com/users'
fetch(URL)
.then(function(response) {
let myData = response.json()
return myData;
})
.then((json) => {
console.log('parsed json', json)
})
.catch(function(ex) {
console.log('parsing failed', ex)
})
} // end componentDidMount
Upvotes: 1
Reputation: 447
REACT NATIVE
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';
export default class SampleApp extends Component {
constructor(props) {
super(props);
this.state = {
data: 'Request '
}
}
componentDidMount = () => {
fetch('http://localhost/replymsg.json', {
mode: "no-cors",
method: "GET",
headers: {
"Accept": "application/json"
},} )
.then(response => {
if (response.ok) {
response.json().then(json => {
console.warn( JSON.stringify(json.msg ));
this.setState({
data: JSON.stringify(json)
})
});
}
});
}
render() {
return (
<Text> {this.state.data}</Text>
);
}
}
AppRegistry.registerComponent('SampleApp', () => SampleApp);
JSON FILE create a file replymsg.json and put below content and it should host to local host like : http://localhost/replymsg.json
{"status":"200ok","CurrentID":28,"msg":"msg successfully reply"}
Upvotes: 1
Reputation: 367
You need to bind current context to the target function
fetch(URL)
.then(function(response) {
return response.json();
})
.then(function(json) {
this.setState({data: json})
}.bind(this))
.catch(function(ex) {
console.log('parsing failed', ex)
})
Upvotes: 0
Reputation: 7126
You're on the right track with this.setState
however this
is no longer in the context of the component when you call it within the function handling the response. Using a =>
function maintains the context of this
.
fetch(URL)
.then((res) => res.json())
.then((json) => this.setState({data: json}));
Upvotes: 3
Reputation: 2037
You have two issues as far as I can see, response.json()
returns a promise, so you don't wanna set myData
to the promise, instead first resolve the promise and then you can access your data.
Second, this
is not in the same scope inside your fetch request, so that's why you are getting undefined, you can try saving the scope of this
outside fetch:
var component = this;
fetch(URL)
.then( (response) => {
return response.json()
})
.then( (json) => {
component.setState({
data: json
})
console.log('parsed json', json)
})
.catch( (ex) => {
console.log('parsing failed', ex)
})
console.log(this.state.data)
Upvotes: 13
Reputation: 186
setState is undefined, because you use classic function syntax instead arrow function. Arrow function takes 'this' keyword from 'parent' function, a classic function() {} creates it's own 'this' keyword. Try this
.then(response => {
let myData = response.json()
// return myData;
this.setState({
data: myData
})
})
Upvotes: 7