【问题标题】:Async call with react native and redux , thunk使用 react native 和 redux 进行异步调用,thunk
【发布时间】:2023-09-18 15:20:01
【问题描述】:

我一直在按照本教程将 redux 集成到我的 react native 应用程序中。

https://github.com/jlebensold/peckish

在我的主页视图中,我无法从我的操作文件夹中调用函数。

一个区别是我在我的应用程序中使用了 react-navigation。想知道我是否需要将 redux 与 react 导航集成才能对所有数据使用 redux?

下面是我一直在做的完整实现代码。

在主屏幕上,我调用 ComponentDidMount 上的 fetchSite 函数来启动与 axios 的异步调用。但我什至无法访问此功能。

很抱歉这篇长篇文章,但我不知道如何使这项工作变得如此困难,因此很难制作更短的代码示例来解释我的应用程序的结构。

如果有任何问题,请告诉我。

index.ios.js

import React from 'react'
import { AppRegistry } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose} from 'redux'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'

import reducer from './app/reducers'
import AppContainer from './app/index'


// middleware that logs actions
const loggerMiddleware = createLogger({ predicate: (getState, action) => __DEV__  });

function configureStore(initialState) {
    const enhancer = compose(
        applyMiddleware(
            thunkMiddleware, // lets us dispatch() functions
            loggerMiddleware,
        ),
    );
    return createStore(reducer, initialState, enhancer);
}

const store = configureStore({});

const App = () => (
    <Provider store={store}>
        <AppContainer />
    </Provider>
);

AppRegistry.registerComponent('Appero', () => App;

reducers/index.js

import { combineReducers } from 'redux';
import * as sitesReducer from './sites'

export default combineReducers(Object.assign(
    sitesReducer,
));

reducers/sites.js

import createReducer from '../lib/createReducer'
import * as types from '../actions/types'

export const searchedSites = createReducer({}, {
    [types.SET_SEARCHED_SITES](state, action) {
        let newState = {};
        action.sites.forEach( (site) => {
            let id = site.id;
            newState[id] = Object.assign({}, site, { id });
        });
        return newState;
    },

});

../lib/createReducer

export default function createReducer(initialState, handlers) {

    return function reducer(state = initialState, action) {
        if (handlers.hasOwnProperty(action.type)) {

            return handlers[action.type](state, action)
        } else {
            return state
        }
    }
}

../actions/types

export const SET_SEARCHED_SITES = 'SET_SEARCHED_SITES';

./app/index 中的 AppContainer

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from './actions';

console.log(ActionCreators); //Properly gathered the functions from the actions folder

import { Root } from './config/router';

window.store = require('react-native-simple-store');
window.axios = require('axios');

class App extends Component {
    render() {
        return (
            <Root />
        )
    }
}

function mapDispatchToProps(dispatch) {

    return bindActionCreators(ActionCreators, dispatch);
}

export default connect(mapDispatchToProps)(App);

'./actions' 中的 ActionCreators;

import * as SiteActions from './sites'

export const ActionCreators = Object.assign({},
    SiteActions,
);

“./actions/sites”中的操作

import * as types from './types' //See above

export function fetchSites(token) {

    return (dispatch, getState) => {

        let instance = axios.create({
            baseURL: url + 'api/',
            timeout: 10000,
            headers: {'Accept' : 'application/json', 'Authorization' : 'Bearer ' + token}
        });

        instance.get('/sites?page=1')
            .then(response => {

                console.log(response.data.data);

                dispatch(setSearchedSites({sites: response.data.data}));

            }).catch(error => {

                console.log(error);
        });

    }
}

export function setSearchedSites({ sites }) {

    return {
        type: types.SET_SEARCHED_SITES,
        sites,
    }
}

基于 react-navigation 的导航根文件 我在这个例子中尽可能简单。

import React from 'react';

import {StackNavigator} from 'react-navigation';

import Home from '../screens/Home';

export const Root = StackNavigator({
    Home: {
        screen: Home,
    }
});

最后是我的主屏幕

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {Text, View} from 'react-native';

class Home extends Component {

    componentDidMount()
    {
        let token = "12345678" //Just for this example
        this.props.fetchSites(token).then( (response) => {
            console.log(response);
        });
    }

    render() {

        return (
            <View>
                <Text>This is the Home view</text>
            </View>
        );
    }
}

function mapStateToProps(state) {
    return {
        searchedSites: state.searchedSites
    };
}

export default connect(mapStateToProps)(Home);

【问题讨论】:

    标签: react-native redux redux-thunk react-navigation


    【解决方案1】:

    要使用操作方法,您需要像这样在主屏幕中连接

    import { fetchSites } from '<your-path>'
    
    // your Home's other code.
    
    const mapDispatchToProps = (dispatch) => {
        return{
            fetchSites:dispatch(fetchSites())
        } 
    }
    
    export default connect(mapStateToProps,mapDispatchToProps)(Home);
    

    之后,您可以随时使用 fetchSites 作为 this.props.fetchSites

    【讨论】:

    • 谢谢。现在,我可以访问 fetchSites 函数了。但是,当我在 axios 日志中使用 console.log 时,我无法在控制台中获取任何内容。什么都没有发生。
    • 厕所,兄弟,如果对您有帮助,请接受并投票。我没有使用 axios,而是在创建 axios 实例后用于调试 put log。如果日志没有打印,那么你的箭头函数有问题,如果它打印,那么使用 axios 有问题。
    • 无法接受未解决问题的答案。访问操作功能是一个步骤,但我无法让异步调用继续工作,这是此处问题的目的。上面的 Axios 调用应该没问题,因为当我从组件调用它时它正在工作。因此,当我控制台时,我无法从 action 函数中的 axios 得到任何答案,这意味着它与我集成 redux 的方式有关。今天早上做了一个关于这个主题的更新教程,并且 axios 调用在示例应用程序上正常工作。如果它工作正常,我会尝试实现它并发布代码。
    • 我的错。使用我之前测试过的新教程实现了 redux,这让我意识到问题出在我的 api 上。不是 redux 实现。感谢您抽出时间来基尚。你得到了你的分数!
    最近更新 更多