Senasiko
Senasiko

Reputation: 109

redux state don't send when use react-navigation

i am using react-navigation and redux in react-native.when i just used redux, the states can send to child by redux. but it don't work when i add react-navigation.
my navigation.js

import {StackNavigator} from 'react-navigation';
import Home from './modules/home/views/Home'
export const StackRouter = StackNavigator({
    Main: {screen: Home},
    initialRouteName: {screen: Home}
});
const firstAction = StackRouter.router.getActionForPathAndParams('Main');
const tempNavState = StackRouter.router.getStateForAction(firstAction);
const initialNavState = StackRouter.router.getStateForAction(
    firstAction,
    tempNavState
);
//navigationreducer
export const stackReducer = (state=initialNavState,action) => {
    debugger
    const newState = StackRouter.router.getStateForAction(action, state);
    return newState || state;
};

my store.js

import React, {Component} from 'react';
import  { connect, Provider } from 'react-redux';
import {createStore, combineReducers, bindActionCreators, applyMiddleware } from 'redux';
import {addNavigationHelpers} from 'react-navigation'
import thunk from 'redux-thunk'
import PropTypes from 'prop-types'

import {StackRouter, stackReducer} from './router'
import home from './modules/home';   



//routerConmponent
class RouterAppWithState extends Component {
    constructor(props){
        super(props)
    }
    render() {
        return (
            <StackRouter navigation={addNavigationHelpers({
                dispatch: this.props.dispatch,
                state: this.props.router,
            })} />
        );
    }
}


//all reducer
const reducer = combineReducers({
    home: home.reducer,
    router: stackReducer,

});

const mapActionToProps = (dispatch) => {
    return {
        home_actions: bindActionCreators(home.actions, dispatch)
    }
};

const mapStateToProps = (state) => {
    debugger;
    return state
};



//connect redux and navigation
const StoreApp = connect(mapStateToProps, mapActionToProps)(RouterAppWithState);

const store = applyMiddleware(thunk)(createStore)(reducer);

export default class RootApp extends Component{
    render() {
        return(
            <Provider store={store}>
                <StoreApp />
            </Provider>
        )
    }

}

my home.js ,just import actions and reducers, and export the module

import actions from './store/actions';
import reducer from './store/reducer'

export default {
    actions,
    reducer
} 

my reducers

export default(state=states, action) => {
    let newState = {...state};
    switch (action.type){
        case TYPES.ADD_COUNT: newState.count = state.count+1;break;
        default: break;
    }
    return newState
};

my actions

const add_count = () => {
    console.log('add');
    return async (dispatch) => {
        dispatch({type: TYPES.ADD_COUNT});
        await new Promise((resolve) => {setTimeout(() => {resolve()} , 3000)});
        dispatch({type: TYPES.ADD_COUNT});
    };
};



export default {
    add_count
}

my view Home.js

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

export default class Home extends Component{
    constructor(props){
        super(props)
    }
    // static contextTypes = {
    //     navigation: React.PropTypes.Object
    // };
    render() {
        debugger
        const {add_count} = this.props.home_actions;
        const {count} = this.props.home;
        return (
            <View>
                <Text >{count}</Text>
                <Button onPress={add_count} title={'add count'}/>
                {/*<Button onPress={() => {navigation.navigate('live')}} title={'live'}/>*/}
            </View>
        )
    }
}

In Home.js function render, this.props is

{
navigation: Object,
screenProps: undefined
}

has not states in redux. but without react-navigation, this.props is

{
home: Object,
home_actions: Object
}

thanks

Upvotes: 2

Views: 990

Answers (1)

hyb175
hyb175

Reputation: 1291

The reason is because now the StackRouter is controlling the rendering of your Home page. The router only pass down a prop called navigation and whatever you pass down from screenProps.

There are two ways that you can achieve a similar behavior as before:

1) In RouterAppWithState's render function, pass down this.props into screenProps like this

<StackRouter navigation={addNavigationHelpers({
            dispatch: this.props.dispatch,
            state: this.props.router,
        })}
  screenProps={this.props}
/>

2) (recommended) The other way is to directly use connect on your home page to connect your Home component to the store and access home specific part of the store. i.e. connect(mapStateToProps)(Home)

Upvotes: 4

Related Questions