react-native - react-navigation 和 api 调用的 Redux 错误
问题描述
我必须进行 api 调用并将数据状态保存在 redux
这就是我目前正在做的事情
import HomeScreen from './pages/home';
const mapStateToProps = (state) => ({
isLoading: state.serviceReducer.isLoading,
error: state.serviceReducer.error,
data: state.serviceReducer.data
});
const mapDispatchToProps = (dispatch) => ({
callService: () => dispatch(callWebservice())
})
export const callWebservice = () => {
console.log("this is getting calles")
return dispatch => {
dispatch(serviceActionPending())
console.log("COMING HERE?")
fetch(`https://news119.herokuapp.com/getData`)
.then(response => {
console.log(response.data)
dispatch(serviceActionSuccess(response.data))
})
.catch(error => {
dispatch(serviceActionError(error))
});
}
}
export const serviceActionPending = () => ({
type: ActionTypes.SERVICE_PENDING
})
export const serviceActionError = (error) => ({
type: ActionTypes.SERVICE_ERROR,
error: error
})
export const serviceActionSuccess = (data) => ({
type: ActionTypes.SERVICE_SUCCESS,
data: data
})
let ReduxAppContainer = connect(mapStateToProps, mapDispatchToProps)(HomeScreen);
这是我的反应导航 js
const AppNavigator = createStackNavigator({
Home: {
screen: ReduxAppContainer,
key: "Home"
},
Details: {
screen: DetailsScreen,
header: {
style: {
backgroundColor: '#00cafe'
}
}
},
Intro: IntroScreen,
Article: {
screen: ExternalScreen,
path: 'news/:id',
},
Settings: SettingsScreen,
Bookmarks: BookmarksScreen,
SingleBookmark: SingleBookmarkScreen
}, {
initialRouteName: "Home",
headerMode: 'none',
transitionConfig: (screen) => handleCustomTransition(screen),
}
);
const AppContainer = createAppContainer(AppNavigator);
const AppNavigatorIntro = createStackNavigator({
Home: {
screen: ReduxAppContainer,
key: "Home"
},
Details: {
screen: DetailsScreen,
style: {
backgroundColor: '#00cafe'
}
},
Intro: IntroScreen,
Article: {
screen: ExternalScreen,
path: 'news/:id',
},
Settings: SettingsScreen,
Bookmarks: BookmarksScreen,
SingleBookmark: SingleBookmarkScreen
}, {
initialRouteName: "Intro",
headerMode: 'none',
transitionConfig: (screen) => handleCustomTransition(screen),
}
);
const AppContainerIntro = createAppContainer(AppNavigatorIntro);
export {
AppContainer,
AppContainerIntro
};
ActionTypes.js
export const SERVICE_PENDING = 'service_pending'
export const SERVICE_ERROR = 'service_error'
export const SERVICE_SUCCESS = 'service_success'
ServiceReducer.js
import * as Actions from './ActionTypes'
const ServiceReducer = (state = {
isLoading: false,
error: undefined,
data: {}
}, action) => {
switch (action.type) {
case Actions.SERVICE_PENDING:
return Object.assign({}, state, {
isLoading: true,
});
case Actions.SERVICE_ERROR:
return Object.assign({}, state, {
isLoading: false,
error: action.error
});
case Actions.SERVICE_SUCCESS:
return Object.assign({}, state, {
isLoading: false,
data: action.data
});
default:
return state;
}
}
export default ServiceReducer;
store.js
import {
combineReducers,
applyMiddleware,
createStore,
compose
} from 'redux';
import thunk from 'redux-thunk';
import {
createLogger
} from 'redux-logger';
import serviceReducer from './ServiceReducer'
const AppReducers = combineReducers({
serviceReducer,
});
const rootReducer = (state, action) => {
return AppReducers(state, action);
}
const logger = createLogger();
let store = createStore(rootReducer, compose(applyMiddleware(thunk)));
export default store;
然后我像这样从主屏幕调用 callService
componentDidMount() {
this.props.callService()
}
componentWillReceiveProps(nextProps) {
if (nextProps.data != null) {
console.log('the state', nextProps)
this.setState({
dataSource: (nextProps.data)
});
}
if (nextProps.error != undefined) {
Alert.alert(
'Error',
nextProps.error,
[{
text: 'Do you want to reload',
onPress: () => this.props.callService()
}, ], {
cancelable: false
})
}
}
但是当我记录这个“状态,nextProps”时,这就是我得到的
06-08 19:24:01.454 29384 32597 I ReactNativeJS: HEYYSYASYundefined
06-08 19:24:01.456 29384 32597 I ReactNativeJS: 0
06-08 19:24:01.458 29384 32597 I ReactNativeJS: undefined
06-08 19:24:01.559 29384 32597 I ReactNativeJS: this is getting calles
06-08 19:24:01.560 29384 32597 I ReactNativeJS: COMING HERE?
06-08 19:24:01.585 29384 32597 I ReactNativeJS: 'the state', { screenProps: undefined,
06-08 19:24:01.585 29384 32597 I ReactNativeJS: navigation:
06-08 19:24:01.585 29384 32597 I ReactNativeJS: { pop: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: popToTop: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: push: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: replace: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: reset: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: dismiss: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: goBack: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: navigate: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: setParams: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: state: { routeName: 'Home', key: 'id-1560002041272-1' },
06-08 19:24:01.585 29384 32597 I ReactNativeJS: router: undefined,
06-08 19:24:01.585 29384 32597 I ReactNativeJS: actions:
06-08 19:24:01.585 29384 32597 I ReactNativeJS: { pop: [Function: pop],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: popToTop: [Function: popToTop],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: push: [Function: push],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: replace: [Function: replace],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: reset: [Function: reset],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: dismiss: [Function: dismiss],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: goBack: [Function: goBack],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: navigate: [Function: navigate],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: setParams: [Function: setParams] },
06-08 19:24:01.585 29384 32597 I ReactNativeJS: getParam: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: getChildNavigation: [Function: getChildNavigation],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: isFocused: [Function: isFocused],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: isFirstRouteInParent: [Function: isFirstRouteInParent],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: dispatch: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: getScreenProps: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: dangerouslyGetParent: [Function],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: addListener: [Function: addListener],
06-08 19:24:01.585 29384 32597 I ReactNativeJS: emit: [Function: emit] },
06-08 19:24:01.585 29384 32597 I ReactNativeJS: isLoading: true,
06-08 19:24:01.585 29384 32597 I ReactNativeJS: error: undefined,
06-08 19:24:01.585 29384 32597 I ReactNativeJS: data: {},
06-08 19:24:01.585 29384 32597 I ReactNativeJS: callService: [Function: callService] }
变量 dataSource 未定义。我确信 api 正在工作,因为如果我在没有 redux 的情况下执行此操作,它可以正常工作。我已经列出了 redux 中使用的所有代码。这是我第一次使用 redux,所以我不知道我做错了什么。
解决方案
我认为问题出在fetch
电话上。
fetch 方法返回一个 Response 对象,而不是直接将数据作为 JSON。
根据文档,您应该拥有:
fetch('https://news119.herokuapp.com/getData')
.then(response => response.json())
.then((responseJson) => {
console.log(responseJson.data)
dispatch(serviceActionSuccess(responseJson.data))
})
.catch((error) => {
dispatch(serviceActionError(error))
});
推荐阅读
- c# - 使用查找表中的 Id 创建新的数据库条目
- java - 为什么我的颤振代码没有在 android 模拟器上执行
- html - 删除网格,如果网格元素为空?
- mysql - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在“NOT NULL”附近使用的正确语法,
- docker - iptables 阻止从主机访问 docker 容器
- reactjs - 反应原生调用 API
- apache2 - Apache2 虚拟主机只显示一个标准页面
- python - 从文本文件创建编号列表
- google-colaboratory - 如何在以下代码中访问相机并在 google colab 上的实时视频上绘制地标
- python-3.x - Python:如何从视频中剪辑/修剪所需部分并将修剪后的视频文件移动到其他目录