[英]Unable to fetch data from api using fetch()
I have a react-native project implemented with redux where I am trying to fetch data from an api using fetch.I am unable to fetch the data from the api.Also,it doesn't give any errors. 我有一个用redux实现的react-native项目,我试图使用fetch从api中获取数据。我无法从api获取数据。此外,它不会给出任何错误。 My code is as shown below:
我的代码如下所示:
Action.js Action.js
//import axios from 'axios';
export const FETCH_DATA = 'fetch_data';
export const FETCH_SUCCESS = 'fetch_success';
export function fetchData() {
return dispatch => {
return(fetch('https://api.myjson.com/bins/fz62x'))
.then(res => res.json())
.then(data => {
dispatch({
type: FETCH_DATA,
payload: data
})
}
)
}
}
I have 2 reducer files: 我有2个reducer文件:
fetch_data.js fetch_data.js
import FETCH_DATA from '../actions'
const initialState = {
result:[],
isFetching: false,
error: false
}
export default function fetchReducer(state = initialState, action) {
switch (action.type) {
case FETCH_DATA: {
return {
...state,
isFetching: true,
result: action.payload.data
}
}
default:
return state
}
}
index.js index.js
import { combineReducers } from 'redux';
import fetchData from './fetch_data';
const rootReducer = combineReducers({
result: fetchData
})
export default rootReducer;
My component where I am trying to access the data fetched from the api: 我试图访问从api获取的数据的组件:
HomeScreen.js HomeScreen.js
import React from 'react';
import { StyleSheet,
Text,
View,
ActivityIndicator
} from 'react-native';
import { bindActionCreators } from 'redux';
import reducer from '../reducers/fetch_data';
import thunk from 'redux-thunk';
import { connect } from 'react-redux';
import { fetchData } from '../actions';
class HomeScreen extends React.Component {
static navigationOptions = {
header: null
}
componentDidMount() {
this.props.fetchData()
}
render() {
const { result, isFetching } = this.props.result;
if (isFetching) {
return(
<View style={{flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<ActivityIndicator size={'large'} />
</View>
)
} else {
return(
<View style={{flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<Text>{result.length}</Text>
</View>
)
}
}
}
function mapStateToProps(state) {
return {
result: state.result
}
}
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ fetchData }, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
},
welcome: {
color: '#FFF',
fontSize: 30
}
})
So,in my Homescreen.js where I try to ge the result of the api in <Text>{result}</Text>
,I get a blank page. 所以,在我的Homescreen.js中,我尝试在
<Text>{result}</Text>
api的<Text>{result}</Text>
,我得到一个空白页面。 If I try to get the length of the result props,I get 0.What is the issue with this code,can anyone please help me with this? 如果我试图得到结果道具的长度,我得到0.这个代码的问题是什么,有人可以帮我这个吗?
NOTE: Also, isFetching
props is returning the default value,ie false, so I am directly navigated to the other page where result prop is mentioned. 注意:另外,
isFetching
props返回默认值,即false,因此我直接导航到提到结果prop的其他页面。
EDIT 1 Updated files for the action,reducer and component are given below: 编辑1动作,减速器和组件的更新文件如下:
Actions.js Actions.js
//import axios from 'axios';
//import { FETCH_DATA, FETCH_DATA_SUCCESS, FETCH_DATA_FAILURE } from '/constants';
export const FETCH_DATA = 'FETCH_DATA';
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
export const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';
export function fetchData() {
return (dispatch) => {
dispatch(getData())
fetch('https://api.myjson.com/bins/fz62x')
.then(res => res.json())
.then(json => dispatch(getDataSuccess(json.results)))
.catch(err => dispatch(getDataFailure(err)))
}
}
function getData() {
return {
type: FETCH_DATA
}
}
function getDataSuccess(data) {
return {
type: FETCH_DATA_SUCCESS,
data
}
}
function getDataFailure() {
return {
type: FETCH_DATA_FAILURE,
}
}
fetch_data.js fetch_data.js
import FETCH_DATA from '../actions';
import FETCH_DATA_SUCCESS from '../actions';
import FETCH_DATA_FAILURE from '../actions';
const initialState = {
result_array:[],
isFetching: false,
error: false
}
export default function fetchReducer(state = initialState, action) {
switch (action.type) {
case FETCH_DATA: {
return {
...state,
isFetching: true,
}
}
case FETCH_DATA_SUCCESS: {
return {
...state,
isFetching: false,
result_array: action.payload
}
}
case FETCH_DATA_FAILURE:
return {
...state,
isFetching: false,
error:true
}
default:
return state
}
}
HomeScreen.js HomeScreen.js
import React from 'react';
import { StyleSheet,
Text,
View,
ActivityIndicator
} from 'react-native';
import { bindActionCreators } from 'redux';
import reducer from '../reducers/fetch_data';
import thunk from 'redux-thunk';
import { connect } from 'react-redux';
import { fetchData } from '../actions';
class HomeScreen extends React.Component {
static navigationOptions = {
header: null
}
componentDidMount() {
this.props.fetchData()
}
render() {
const { result, isFetching } = this.props.result;
if (isFetching) {
return(
<View style={{flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<ActivityIndicator size={'large'} />
</View>
)
} else {
return(
<View style={{flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<Text>{result}</Text>
</View>
)
}
}
}
function mapStateToProps(state) {
return {
result_array: state.result.result_array
}
}
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ fetchData }, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
},
welcome: {
color: '#FFF',
fontSize: 30
}
})
I'm not sure about your problem but hope this help. 我不确定你的问题,但希望这有帮助。
First, Your Action.js
, you dispatch payload with array: 首先,您的
Action.js
,您使用数组调度有效负载:
dispatch({
type: FETCH_DATA,
payload: data
})
that data
is array 那个
data
是数组
[
{ createdOn: '', taskList: [{}, {}, ...] },
{ createdOn: '', taskList: [{}, {}, ...] },
...
]
In your fetch_data.js
You received payload with array but access .data
it will got undefined, you have to change to result: action.payload
在你的
fetch_data.js
你收到了带数组的有效负载,但访问.data
它将被定义为未定义,你必须改为result: action.payload
return {
...state,
isFetching: true,
result: action.payload.data // <-- undefined
}
but I think you should have type FETCH_DATA
to return { isFetching: true }
and FETCH_SUCCESS
return { isFetching: false, result: action.payload
like this 但我认为你应该有类型
FETCH_DATA
来返回{ isFetching: true }
和FETCH_SUCCESS
返回{ isFetching: false, result: action.payload
像这样
// action.js
fetchData() {
dispatch({
type: FETCH_DATA
})
return fetch('https://api.myjson.com/bins/fz62x')
.then(res => res.json())
.then(data => {
dispatch({
type: FETCH_SUCCESS,
payload: data
})
})
}
// fetch_data.js
switch (action.type) {
case FETCH_DATA: {
return {
...state,
isFetching: true
}
}
case FETCH_SUCCESS: {
return {
...state,
isFetching: false,
result: action.payload
}
}
}
but It looks a bit weird because you got 0 when use get the length of result, it should be undefined
unless it return defaultValue of state that result
is empty array 但它看起来有点奇怪,因为你在使用获得结果的长度时得到0,它应该是
undefined
除非它返回defaultValue状态, result
是空数组
There are a few things you need to fix. 您需要解决一些问题。 It would be better if you upload the codes to github or codesandbox then we can understand you code structure easier.
如果你将代码上传到github或codesandbox会更好,那么我们可以更容易地理解你的代码结构。
First of all, return (fetch('url')).then
or return fetch(url).then
, both of them work as you expect, but you should keep in mind that the redux-thunk
doesn't care about you return value, this promise has nothing to do, that's alright, it doesn't need to do anything. 首先,
return (fetch('url')).then
或return fetch(url).then
return (fetch('url')).then
,它们都按预期工作,但你应该记住, redux-thunk
并不关心你的回归价值,这个承诺无关,没关系,它不需要做任何事情。
Let's fix your syntax error in fetch_data.js
first: 让我们先修复
fetch_data.js
的语法错误:
import FETCH_DATA from '../actions'
should be : 应该 :
import { FETCH_DATA } from '../actions' // I don't know why didn't your build tool report an error here.
According to your purpose, I think you should import the FETCH_SUCCESS
here as well. 根据您的目的,我认为您也应该在这里导入
FETCH_SUCCESS
。
Then we can talk about your action and reducer flow : 然后我们可以谈谈你的行动和减速器流程:
return(fetch('https://api.myjson.com/bins/fz62x'))
.then(res => res.json())
.then(data => {
dispatch({
type: FETCH_DATA,
payload: data
})
}
)
}
and reducer : 和减速机:
switch (action.type) {
case FETCH_DATA: {
return {
...state,
isFetching: true,
result: action.payload.data
}
}
default:
return state
}
You only deal with FETCH_DATA
(and I think you probably should use FETCH_SUCCESS
here), another action type should be dispatch and parse as well. 你只处理
FETCH_DATA
(我想你可能应该在这里使用FETCH_SUCCESS
),另一个动作类型也应该是dispatch和parse。
I will suggest the flow like this : 我会建议这样的流程:
Action.js
: Action.js
:
export const FETCH_DATA = "fetch_data";
export const FETCH_SUCCESS = "fetch_success";
export function fetchData() {
return dispatch => {
fetch("https://api.myjson.com/bins/fz62x")
.then(res => res.json())
.then(data => {
dispatch({
type: FETCH_SUCCESS,
payload: data
});
});
dispatch({
type: FETCH_DATA
});
};
}
With this you now dispatch FETCH_DATA
to tell the application you start to fetch data first, and dispatch FETCH_SUCCESS
when fetch succeed. 有了这个,你现在调度
FETCH_DATA
告诉应用程序你首先开始获取数据,并在获取成功时调度FETCH_SUCCESS
。
And the fetch_data.js
: 和
fetch_data.js
:
import { FETCH_DATA, FETCH_SUCCESS } from "./actions";
const initialState = {
result: [],
isFetching: false,
error: false
};
export default function fetchReducer(state = initialState, action) {
switch (action.type) {
case FETCH_DATA: {
return {
...state,
isFetching: true,
error: false
};
}
case FETCH_SUCCESS: {
return {
result: action.payload, // The action.payload.data isn't what you want
isFetching: false,
error: false
};
}
default:
return state;
}
}
And now your reducer will respond correctly with FETCH_DATA
and FETCH_SUCCESS
现在,您的reducer将使用
FETCH_DATA
和FETCH_SUCCESS
正确响应
And another thing is I don't know why you import thunk and reducer in your Homescreen.js
, it should not be there if you are not going to create you redux store there (I assume that you have a <Provider store={store}>{...your application}</Provider>
upon the Homescreen
which you should have) 另一件事是我不知道为什么你在
Homescreen.js
导入thunk和reducer,如果你不打算在那里创建你的redux存储,它应该不存在(我假设你有一个<Provider store={store}>{...your application}</Provider>
您应该拥有的主Homescreen
上的<Provider store={store}>{...your application}</Provider>
You must have 50 reputation to comment
你必须有50个评论的声誉
Sorry, but i just seen that your edit 1 has something wrong. 对不起,但我刚看到你的编辑1出了问题。 iam i right
我是对的
case FETCH_DATA_SUCCESS: {
return {
...state,
isFetching: false,
result_array: action.payload <-- this is undefined. it should be action.data from your action
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.