Alexey K
Alexey K

Reputation: 6723

React Native Navigation with Redux - undefined is not a function

I try to setup react-native-navigation but I tun in problem

enter image description here

My code is following

app.js

import React from 'react';

import { Provider } from 'react-redux'
import { Navigation } from 'react-native-navigation';
import registerScreens from './screens'

import configureStore from './src/store/configureStore';

export default class App extends React.Component {

  constructor(props) {
    super(props)

    const store = configureStore()

    registerScreens(store, Provider);

    startApp()
  }

  startApp() {
    Navigation.startSingleScreenApp({
      screen: {
        screen: 'ior.Login', 
        title: 'Welcome', 
        navigatorStyle: {}, 
        navigatorButtons: {} 
      },
      drawer: {} ,
      passProps: {}, 
      animationType: 'slide-down' 
    });
  }
}

configureStore.js

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

export default function configureStore() {
    return createStore(
        reducers,
        {},
        applyMiddleware(ReduxThunk)
    );
}

screens.js

import { Navigation } from 'react-native-navigation';
import Login from './src/components/Login'

export function registerScreens(store, Provider) {
    Navigation.registerComponent('ior.Login', () => Login, store, Provider);
}

Login.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
import { loginChanged, passwordChanged, loginUser } from '../actions';

class Login extends React.Component {
    onLoginChange(text) {
        this.props.loginChanged(text)
    }

    onPasswordChange(text) {
        this.props.passwordChanged(text)
    }

    onPress() {
        this.props.loginUser(this.props.email, this.props.password)
    }

    render() {
        return (
            <View style={styles.container}>
                <TextInput
                style={styles.textField}
                onChangeText={this.onLoginChange.bind(this)}
                value={this.props.email}
                placeholder={"Логин"}
                 />
                <TextInput
                style={styles.textField}
                onChangeText={this.onPasswordChange.bind(this)}
                value={this.props.password}
                placeholder={"Пароль"}
                />
                <Button onPress={this.onPress.bind(this)} title={"Войти"}/>
          </View>
        )
    }
}

const styles = StyleSheet.create({
    textField: {
      flex: 1,
      width: '80%',
      height: 100,
    },
    container: {
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
      flex: 0.3,
      marginTop: 210
    },
    button: {
      width: '100%'
    }
  });

const mapStateToProps = state => {
    return {
        email: state.login.email,
        password: state.login.password
    }
}

export default connect(mapStateToProps, { loginChanged, passwordChanged, loginUser })(Login)

actions/index.js

import axios from 'axios'

export const loginChanged = (text) => {
    return {
        type: 'LOGIN_CHANGED',
        payload: text
    }
}

export const passwordChanged = (text) => {
    return {
        type: 'PASSWORD_CHANGED',
        payload: text
    }
}

export const loginUser = (email, password) => {
    const creds = { mail: email, password: password }
    console.log(creds)
    return (dispact) => {
        axios.post('http://192.168.1.10:3000/users/auth', creds)
        .then(response => console.log(response))
        .catch( err => console.log(err))
     }
}

What am I doing wrong ?

Upvotes: 1

Views: 527

Answers (1)

nem035
nem035

Reputation: 35481

The issue is that registerScreens is exported as a named export but you're importing it as a default export.

import registerScreens from './screens'
//     ^ this is how you import a default export

You should add export default to registerScreens

export default function registerScreens(store, Provider) {
    // ...
}

Or import it like a named export:

import { registerScreens } from './screens'

Additionally, you are calling a class method startApp() as if it was a normal function but it's a method on your class.

export default class App extends React.Component {
  constructor(props) {
    // ...
    startApp()
    // ^calling like a simple function
  }
}

You must call it from the context:

export default class App extends React.Component {
  constructor(props) {
    // ...
    this.startApp()
    // ^calling it like a method
  }
}

Upvotes: 1

Related Questions