如何在 React 中处理 fetch API AJAX 响应
Posted
技术标签:
【中文标题】如何在 React 中处理 fetch API AJAX 响应【英文标题】:How to handle fetch API AJAX response in React 【发布时间】:2017-02-09 11:07:51 【问题描述】:我正在使用 React 中的 fetch API 发出一个简单的 AJAX 请求,特别是在 componentDidMount()
函数中。
它正在工作,因为控制台似乎正在记录结果。但是,我不知道如何访问响应...
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
我尝试在 fetch 方法之外访问 myData
,但这会引发错误,指出它未定义。所以只能在函数范围内访问。
然后我尝试了这个:
.then(function(response)
let myData = response.json()
// return myData;
this.setState(
data: myData
)
)
这一次,我得到Cannot read property 'setState' of undefined(…)
如何将获取响应传递给状态,甚至只是一个全局变量?
更新
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;
【问题讨论】:
【参考方案1】:您在this.setState
的正确轨道上,但是当您在处理响应的函数中调用它时,this
不再位于组件的上下文中。使用=>
函数维护this
的上下文。
fetch(URL)
.then((res) => res.json())
.then((json) => this.setState(data: json));
【讨论】:
谢谢。这是有道理的,但我仍然没有得到想要的结果。请看我的更新... 您仍然在响应处理程序的上下文中引用this
,而不是在组件的上下文中。您要么需要将组件绑定到您的函数,要么使用胖箭头函数来维护 this 的上下文。
我现在看到你的更新了。您现在已经用箭头函数声明了componentDidMount
。这实质上会破坏您的组件,因为现在该箭头函数内的this
不再位于组件的上下文中。你应该像以前一样声明它componentDidMount()
。获取响应中的响应处理程序是需要使用箭头函数的处理程序。
仍然无法正常工作:/ 更改了我的更新...myData
仍然持有我在状态初始化中声明的null
值...
您是否尝试过在您的render()
方法中渲染this.state.data
?一旦你调用this.setState(data: myData)
,它将触发你的组件的渲染。此外,如果您使用的是 Chrome,您可以使用 React Devtools Chrome 扩展程序进行调试。它将允许您在调用 this.setState(data: myData)
后查看组件的状态。【参考方案2】:
setState 未定义,因为您使用经典函数语法而不是箭头函数。箭头函数从 'parent' 函数中获取 'this' 关键字,经典的 function() 创建它自己的 'this' 关键字。 试试这个
.then(response =>
let myData = response.json()
// return myData;
this.setState(
data: myData
)
)
【讨论】:
【参考方案3】:据我所知,你有两个问题,response.json()
返回一个承诺,所以你不想将myData
设置为承诺,而是首先解决承诺,然后你可以访问你的数据。
其次,this
在您的 fetch 请求中不在同一个范围内,这就是您未定义的原因,您可以尝试将 this
的范围保存在 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)
【讨论】:
谢谢老兄!我为此浪费了 3 个小时【参考方案4】:你需要将当前上下文绑定到目标函数
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)
)
【讨论】:
【参考方案5】:反应原生
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 文件 创建一个文件 replymsg.json 并放在下面的内容,它应该托管到本地主机,如:http://localhost/replymsg.json
"status":"200ok","CurrentID":28,"msg":"msg successfully reply"
【讨论】:
【参考方案6】:通过使用“=>”而不是函数来更改访问响应数据的方式,使其处于相同的上下文中。
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
【讨论】:
以上是关于如何在 React 中处理 fetch API AJAX 响应的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 中使用 fetch() API 来设置状态
如何在带有 Jest 的 react-native 中使用模拟的 fetch() 对 API 调用进行单元测试