简体   繁体   中英

How to define a variable/method in the props with redux in React Native

I'm implementing an authentication, I have a problem with the props.

When I display the props, I don't have the props authState so I got an error that I don't understand where it comes from and I can't solve it. Here's the error:

[21:42:10] TypeError: undefined is not an object (evaluating '_this$props$authState.app_started')

This error is located at:
    in App (at withExpoRoot.js:22)
    in RootErrorBoundary (at withExpoRoot.js:21)
    in ExpoRootComponent (at renderApplication.js:34)
    in RCTView (at View.js:44)
    in RCTView (at View.js:44)
    in AppContainer (at renderApplication.js:33)

App.js

import ... 

export default class App extends React.Component {

  componentDidMount() {
    this.props.checkLogin();
  }
  _renderSplash = ()=>{
    return (
        <View>
          <ActivityIndicator size="large"/>
          <Text children='Loading...'/>
        </View>
    );
  }

  _renderRoot = (authenticated)=>{
    const Navigation = Navigation(authenticated);
    return <Navigation/>;
  }

  render() {
      console.log(this.props); // it don't show -> this.props.authState
      const {app_started, authenticated} = this.props.authState;
      const Root = connect(mapStateToProps, mapDispatchToProps) ((app_started ? this._renderRoot(authenticated): this._renderSplash));
      return (
        <Provider store={configureStore}>
          <Root/>
        </Provider>
      );
  }

}
const mapStateToProps = (state) => {
      return {
        authState: state.authState
      }
};
const mapDispatchToProps = (dispatch, ownProps)=>{
  return {
    async checkLogin(){
      const isLoggin = await AsyncStorage.getItem('authenticated').catch(e => console.log(e));
      if(isLoggin){
        dispatch(actionCreator(LOGIN_SUCCESS))
      }
      dispatch(actionCreator(APP_LOADED))
    }
  }
};

configureStore.js

import {combineReducers, createStore} from 'redux';
import authStateReducer from './authStateReducer';

const rootReducer = combineReducers({
    authState: authStateReducer
});

const configureStore = () => {
    return createStore(rootReducer);
};

export default createStore(configureStore);

navigation.js

import ...
const Navigation = (authenticated)=>createStackNavigator({
    login: {
        screen: Login,
        navigationOptions: {
            title: 'login'
        }
    },
    dashboard: {
        screen: Dashboard,
        navigationOptions: {
            title: 'dashboard'
        }
    }
}, {
    initialRouteName: authenticated ? 'dashboard': 'login'
});
export default Navigation;

authStateReducer.js

import ...
const authStateReducer = (state={app_started: false, authenticated: false} , action)=>{
    let next_state;
    switch (action.type) {
        case LOGIN_SUCCESS:
            next_state = {
                ...state, authenticated: true
            };
            return next_state;
        case LOGOUT:
            next_state = {
                ...state, authenticated: false
            };
            return next_state;
        case  APP_LOADED:
            next_state = {
                ...state, app_started: true
            };
            return next_state;
        default:
            return state;
    }
}

export default authStateReducer;

Login.js

import ...
class Login extends React.PureComponent{
    _login = ()=>{
        // check the fields
        let token = 'whatever';
        this.props.authSuccess(token);
    };
    render() {
        return (
            <View>
                 <TextInput.../>
                 <TextInput...
                     onSubmitEditing={this._login}
                 />
                 <Button ... onPress={this._login}/>
            </View>
        );
    }
}

const mapStateToProps = (state) => {
    return state

};
export const actionCreator = (action, payload=null)=>{return{type: action, payload: payload}};

const mapDispatchToProps = (dispatch,ownProps)=>{
    return {
        authSuccess: (token)=>{
            AsyncStorage.multiSet([['token',token], ["login", '1']]);
            dispatch(actionCreator(LOGIN_SUCCESS))
        }
    }
};

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

I found the error, it's in configureStore.js

A lightweight React-Native Redux Boilerplate with ready to use modern technologies. This Repo provides you a good state of the art start for your next React-Native project. Please check the link

https://github.com/Anyline/react-native-redux-boilerplate

In App.js authState is undefined because you need to connect your mapStateToProps and mapDispatchToProps or none of it will be available in this.props.

It should look like:

App.js

import...
import { connect } from 'react-redux';

class App extends React.Component { // <- get rid of export default here
...

// after mapStateToProps and mapDispatchToProps
export default connect(mapStateToProps, mapDispatchToProps)(App);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM