0

I have been following this tutorial to integrate redux into my react native app.

https://github.com/jlebensold/peckish

On my Home view, I'm not able to call the functions from my action folder.

One difference is that I'm using react-navigation in my app. Wonder if I need to integrate redux with react navigation to be able to use redux for all data?

Below is the full implementation code I have been doing.

On the Home screen, I call the fetchSite function on ComponentDidMount to launch an async call with axios. But I can't even access to this function.

Sorry for this long post but I can't figure out how to make this work so quite difficult to make a shorter code sample to explain the structure of my app.

Let me know if any question.

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';

AppContainer in ./app/index

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);

ActionCreators in './actions';

import * as SiteActions from './sites'

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

Actions in './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,
    }
}

Root file for navigation based on react-navigation I made it as simple as possible for this example.

import React from 'react';

import {StackNavigator} from 'react-navigation';

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

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

And finally my Home screen

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);

1 Answer 1

1

To use action methods you need to connect in home screen like this

import { fetchSites } from '<your-path>'

// your Home's other code.

const mapDispatchToProps = (dispatch) => {
    return{
        fetchSites:dispatch(fetchSites())
    } 
}

export default connect(mapStateToProps,mapDispatchToProps)(Home);

after that you can use fetchSites as this.props.fetchSites whenever you want.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks. Now, I'm able to access the fetchSites function. However, when I console.log inside the axios log, I can't get anything in the console. Nothing is happening.
Wc, bro, Accept and upvote if it helps you. I didn't use axios, but for debugging put log after creating an instance of axios. if the log is not printing then there is a problem in your arrow function and if it prints then there is a problem in using axios.
Can't accept an answer that didn't solved the issue. Accessing the action function is one step but I can't get the async call to be working still which is the purpose of the question here. Axios call above should be fine as it is working when I call it from the component. So the fact I can't get any answer from axios in the action function when I console it means it is related to the way I have integrated redux. Did a more recent tutorial this morning on this topic and the axios call works properly on the sample app. I'll try to implement it and post the code if it is working properly.
my bad. Implemented redux with the new tutorial I tested earlier which made realised the issue is with my api. Not the redux implementation. Thank you for your time Kishan. You got your score!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.