gpt4 book ai didi

react-native - 使用 redux 从 native react 的 API 中获取数据

转载 作者:行者123 更新时间:2023-12-03 14:30:15 25 4
gpt4 key购买 nike

我正在开发一个 react-native 项目,我正在尝试使用 axios 库从 api 获取数据并显示数据。因此,我的应用程序首先显示启动画面,然后需要导航到由选项卡组成的页面。选项卡将包含来自 api 的数据。

所以,我试图在我的主页中初始化我的商店,它出现在启动画面之后。我在 2 个不同的文件中分别定义了我的 reducer 和 Action 。

App.js 文件

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { StackNavigator } from 'react-navigation';
import SplashScreen from './src/components/SplashScreen';
import HomeScreen from './src/components/HomeScreen';

const Navigation = StackNavigator({
Splash: {
screen: SplashScreen
},
Home: {
screen: HomeScreen
}
})

export default Navigation;

我的 SplashScreen 组件:
import React from 'react';
import { StyleSheet,
Text,
View,
} from 'react-native';

export default class SplashScreen extends React.Component {
static navigationOptions = {
header: null
}

componentWillMount() {
setTimeout(() => {
this.props.navigation.navigate('Home')
},2000)
}

render() {
return(
<View style={styles.container}>
<Text style={styles.welcome}>Splash Screen</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'skyblue'
},
welcome: {
color: '#FFF',
fontSize: 30
}
})

我的主屏幕组件:
import React from 'react';
import { StyleSheet,
Text,
View,
} from 'react-native';

export default class SplashScreen extends React.Component {
static navigationOptions = {
header: null
}

componentWillMount() {
setTimeout(() => {
this.props.navigation.navigate('Home')
},2000)
}

render() {
return(
<View style={styles.container}>
<Text style={styles.welcome}>Splash Screen</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'skyblue'
},
welcome: {
color: '#FFF',
fontSize: 30
}
})




import React from 'react';
import { StyleSheet,
Text,
View,
} from 'react-native';

export default class SplashScreen extends React.Component {
static navigationOptions = {
header: null
}

componentWillMount() {
setTimeout(() => {
this.props.navigation.navigate('Home')
},2000)
}

render() {
return(
<View style={styles.container}>
<Text style={styles.welcome}>Splash Screen</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'skyblue'
},
welcome: {
color: '#FFF',
fontSize: 30
}
})

Action.js 文件
import axios from 'axios';
export const FETCH_DATA = 'fetch_data';

const API = 'https://api.myjson.com/bins/fz62x';

export function fetchData() {
const request = axios.get(API);

return dispatch => {
return request.then((data) => {
dispatch({
type: FETCH_DATA,
payload: data
})
})
}
}

我的 reducer
import { FETCH_DATA } from './actions';

export default function(state={}, action) {
switch(action.type) {
case FETCH_DATA:
return {
...state,
action.payload
};

default:
return state;
}
}

任何人都可以告诉我这是否是正确的方法?如果不是,那么正确的方法是什么?

最佳答案

我会说没有正确或不正确的方法来做到这一点。但我可以分享一种我通常使用的模式。

首先,我会为不同的文件创建单独的文件夹。 Action 文件夹中的 Action , reducer 文件夹中的 reducer 等......我会创建单独的 constants.js文件和 configureStore.js文件并将它们放在项目根目录中。

我会放弃 Axios 库,只使用 Fetch API用于数据获取。考虑到您的代码,我会执行以下操作。

创建 configureStore.js项目中的文件 root目录。我建议您使用 Redux-Thunk .您可以从 here 找到更多信息.

configureStore.js

import { createStore, applyMiddleware } from 'redux';
import app from './reducers';
import thunk from 'redux-thunk';

export default function configureStore() {
let store = createStore(app, applyMiddleware(thunk))
return store
}

App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { StackNavigator } from 'react-navigation';
import configureStore from './configureStore';
import HomeScreen from './screens/HomeScreen';

const NavigationApp = StackNavigator({
HomeScreen: { screen: HomeScreen }
})

const store = configureStore()

export default class App extends Component {

render() {
return (
<Provider store={store}>
<NavigationApp />
</Provider>
);
}
}

让我们创建 constants.js我们把它放在项目中 root目录。

常量.js
export const FETCHING_TODOS = 'FETCHING_TODOS';
export const FETCH_TODOS_SUCCESS = 'FETCH_TODOS_SUCCESS';
export const FETCH_TODOS_FAILURE = 'FETCH_TODOS_FAILURE';

现在让我们继续创建我们的 Action 文件,该文件将放在 actions 中。文件夹。让我们将其命名为 fetchToDos.js .让我们使用 Fetch API 创建一个简单的函数.

fetchToDos.js
import { FETCH_TODOS_SUCCESS, FETCH_TODOS_FAILURE, FETCHING_TODOS } from '../constants';

export function fetchToDos() {

return (dispatch) => {
dispatch(getTodos())

return(fetch('https://api.myjson.com/bins/fz62x'))
.then(res => res.json())
.then(json => {

return(dispatch(getToDosSuccess(json)))
})
.catch(err => dispatch(getToDosFailure(err)))
}
}

function getToDos() {

return {
type: FETCHING_TODOS
}
}

function getToDosSuccess(data) {

return {
type: FETCH_TODOS_SUCCESS,
data
}
}

function getToDosFailure() {
return {
type: FETCH_TODOS_FAILURE
}
}

fetchToDos.js 与 Axios
import { FETCH_TODOS_SUCCESS, FETCH_TODOS_FAILURE, FETCHING_TODOS } from '../constants';
import axios from 'axios';

export function fetchToDos() {

return (dispatch) => {
dispatch(getUser())
axios.get('https://api.myjson.com/bins/fz62x')
.then(function (response) {

// handle your response here, create an object/array/array of objects etc...
// and return it in dispatch(getToDosSuccess(data over here))

return(dispatch(getToDosSuccess(response.data)))
})
.catch(err => dispatch(getToDosFailure(err)))
}
}

// rest is the same...

继续使用 reducer 。让我们创建两个文件 - index.js , todos.js并将它们放入 reducers文件夹。

todos.js
import { FETCH_TODOS_SUCCESS, FETCH_TODOS_FAILURE, FETCHING_TODOS } from '../constants';

const initialState = {
todos: [],
isFetching: false,
error: false
}

export default function todosReducer(state = initialState, action) {

switch(action.type) {
case FETCHING_TODOS:
return {
...state,
isFetching: true
}
case FETCH_TODOS_SUCCESS:
return {
...state,
isFetching: false,
todos: action.data
}
case FETCH_TODOS_FAILURE:
return {
...state,
isFetching: false,
error: true
}
default:
return state
}
}

index.js
import { combineReducers } from 'redux';
import todos from './todos';

const rootReducer = combineReducers({
todos
})

export default rootReducer

基本上“举重”就完成了。我只会创建一个屏幕,因为让我们假设用户会在主屏幕上点击后退按钮(Android),他们最终会出现在该启动屏幕上。所以在这个例子中,我将只使用一个屏幕。

HomeScreen.js
import React, { Component } from 'react';
import {
View,
Text,
ActivityIndicator
} from 'react-native';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { fetchTodos } from '../actions/fetchTodos';

class HomeScreen extends Component {

componentDidMount() {

this.props.fetchTodos()

}

render() {

const { todos, isFetching } = this.props.todos

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>todos.length</Text>
</View>
)
}

}

}

function mapStateToProps(state) {
return {
todos: state.todos
}
}

function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ fetchTodos }, dispatch)
}
}

export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)

我真的希望你觉得这个概念很有用,因为我可以从我的经验中说,当我第一次开始时它帮助了我很多,它帮助我更好地理解了 redux 的整个概念。

抱歉,如果有任何错别字和错误。我很忙。

关于react-native - 使用 redux 从 native react 的 API 中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48178468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com