路线“”的组件必须是React组件

时间:2019-07-04 14:13:11

标签: react-native redux react-redux

我是react-native的新手,正在尝试使用Redux框架,我遇到了这个问题:(路由''的组件必须是React组件):

谢谢。

Screen Error

Index.js

import React from 'react'
import { Provider } from 'react-redux'
import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import Menu from './app/componnts/Menu'
import storeConfig from './app/store/storeConfig'

const store = storeConfig()
const Redux = () => {
    return (
        <Provider store={store}>
            <Menu />
        </Provider>
    )
}

AppRegistry.registerComponent(appName, () => Redux);

Menu.js

import React, { Component } from 'react'
import {
    StyleSheet,
    SafeAreaView,
    ScrollView,
    Dimensions,
    View,
    Image,
    Text
} from 'react-native'
import { createDrawerNavigator, DrawerItems, } from 'react-navigation'
import Login from './Login/Login'
import Viatura from './Viatura/Viatura'


export default class App extends Component {
    render() {
        return (
            <AppDrawerNavigator />
        )
    }
}

const CustomDrawerComponent = (props) => (
    <SafeAreaView style={{ flex: 1 }}>
        <ScrollView>
            <DrawerItems {...props} />
        </ScrollView>
    </SafeAreaView>
)

const AppDrawerNavigator = createDrawerNavigator({
    Login,
    Viatura,
}, {
        contentComponent: CustomDrawerComponent,
        drawerWidth: 300,
        contentOptions: {
            activeTintColor: 'orange'
        }
    })

Login.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { loginStore } from '../../store/actions/user.js';
import { Text, View, ImageBackground, Dimensions, Image, TextInput, TouchableOpacity, Alert } from 'react-native'
import Icon from 'react-native-vector-icons/FontAwesome'
import axios from 'axios'
import { createIconSetFromIcoMoon } from 'react-native-vector-icons'
import { API_MOTORISTAS_LOGIN } from '../../config'
import icoMoonConfig from '../../resources/fonts/selection.json'
import styles from './styles'
import bgImage from '../../images/fundo-vertical-preto.jpg'
import logo from '../../images/logo-tg-v-01.png'

const MyIcon = createIconSetFromIcoMoon(icoMoonConfig, 'icomoon', 'icomoon.ttf');

class Login extends Component {

    constructor(props) {
        super(props)
        this.state = {
            user: '',
            password: '',
        }
        this.loginUser = this.loginUser.bind(this)
    }

    loginUser = () => {
        try {
            const { user, password } = this.state
            this.setState({ error: '', })

            axios.post(`${API_MOTORISTAS_LOGIN}`,
                {
                    'param1': this.state.user,
                    'param2': this.state.password
                }, {
                    "headers": {
                        'Content-Type': 'application/json',
                    }
                }).then((response) => {
                    if (response.data.error) {
                        Alert.alert((response.data.error));
                    } else {
                        this.props.onLogin({ ...this.state })
                        const api_token = response.data.api_token
                        this.props.navigation.navigate('Viatura', {
                            api_token: api_token,
                        })
                    }
                })
                .catch((error) => {
                    console.log("axios error:", error);
                });
        } catch (err) {
            Alert.alert((err))
        }
    }

    static navigationOptions = {
        drawerIcon: ({ tintColor }) => (
            <MyIcon name="fonte-tg-33" style={{ fontSize: 24, color: tintColor }} />
        )
    }

    render() {
        return (
            <ImageBackground
                source={bgImage}
                style={styles.backgroundContainer}>
                <View
                    style={{
                        height: (Dimensions.get('window').height / 10) * 10,
                        alignItems: 'center',
                        justifyContent: 'center',
                    }}>
                    <View style={styles.logoContainer}>
                        <Image source={logo} style={styles.logo} />
                    </View>
                    <View style={styles.inputText}>
                        <View style={styles.iconContainer}>
                            <MyIcon style={styles.icon} name="fonte-tg-39" size={25} />
                        </View>
                        <TextInput
                            style={styles.input}
                            placeholder={'User'}
                            placeholderTextColor={'rgba(0, 0, 0, 0.6)'}
                            underlineColorAndroid='transparent'
                            value={this.state.user}
                            onChangeText={user => this.setState({ user })}
                        />
                    </View>
                    <View style={styles.inputText}>
                        <View style={styles.iconContainer}>
                            <MyIcon style={styles.icon} name="fonte-tg-73" size={25} />
                        </View>
                        <TextInput
                            style={styles.input}
                            placeholder={'Password'}
                            secureTextEntry={true}
                            placeholderTextColor={'rgba(0, 0, 0, 0.6)'}
                            underlineColorAndroid='transparent'
                            value={this.state.password}
                            onChangeText={password => this.setState({ password })}
                        />
                    </View>
                    <View style={styles.buttonsLogin}>
                        <TouchableOpacity style={styles.btnSair}>
                            <Text style={styles.text}> Sair </Text>
                        </TouchableOpacity>
                        <TouchableOpacity onPress={this.loginUser} style={styles.btnEntrar}>
                            <Text style={styles.text}> Entrar </Text>
                        </TouchableOpacity>
                    </View>
                </View>
            </ImageBackground>
        )
    }
}

const mapDispatchToProps = dispatch => {
    return {
        onLogin: user => dispatch(loginStore(user))
    }
}

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

actionTypes.js

export const USER_LOGGED_IN = 'USER_LOGGED_IN';
export const USER_LOGGED_OUT = 'USER_LOGGED_OUT';

user.js(内部操作文件夹)

import { USER_LOGGED_IN, USER_LOGGED_OUT } from './actionTypes'

export const login = user => {
    return {
        type: USER_LOGGED_IN,
        payload: user
    }
}

export const logout = () => {
    return {
        type: USER_LOGGED_OUT,
    }
}

user.js(在reducers文件夹内)

import { USER_LOGGED_IN, USER_LOGGED_OUT } from '../actions/actionTypes'

const initalState = {
    user: null,
    password: null
}

const reducer = (state = initalState, action) => {
    switch (action.type) {
        case USER_LOGGED_IN:
            return {
                ...state,
                user: action.paypload.user,
                password: action.paypload.password
            }
        case USER_LOGGED_OUT:
            return {
                ...state,
                user: null,
                password: null,
            }
        default:
            return state
    }
}

export default reducer

storeConfig.js

import { createStore, combineReducers } from 'redux'
import userReducer from './reducers/user'

const reducers = combineReducers({
    user: userReducer,
})

const storeConfig = () => {
    return createStore(reducers)
}

export default storeConfig

正如我在博文开头所说,我仍然是react-native的初学者,所以我发布了几段代码,以便我可以尽可能清楚地了解我的处境。

2 个答案:

答案 0 :(得分:1)

我认为您的屏幕没有正确设置export default

您可以更改此代码吗?

import React, { Component } from 'react'
import {
    StyleSheet,
    SafeAreaView,
    ScrollView,
    Dimensions,
    View,
    Image,
    Text
} from 'react-native'
import { createDrawerNavigator, DrawerItems, } from 'react-navigation'
import Login from './Login/Login'
import Viatura from './Viatura/Viatura'


export default class App extends Component {
    render() {
        return (
            <AppDrawerNavigator />
        )
    }
}

const CustomDrawerComponent = (props) => (
    <SafeAreaView style={{ flex: 1 }}>
        <ScrollView>
            <DrawerItems {...props} />
        </ScrollView>
    </SafeAreaView>
)

const AppDrawerNavigator = createDrawerNavigator(
{
    Login : () => <Login />,
    Viatura : () => <Viatura />
}, 
{
        contentComponent: CustomDrawerComponent,
        drawerWidth: 300,
        contentOptions: {
            activeTintColor: 'orange'
        }
}
)

OR

import { Login } from './Login/Login'
import { Viatura } from './Viatura/Viatura'

...
const AppDrawerNavigator = createDrawerNavigator(
{
    Login : { screen: Login },
    Viatura : { screen: Viatura }
}, 
{
        contentComponent: CustomDrawerComponent,
        drawerWidth: 300,
        contentOptions: {
            activeTintColor: 'orange'
        }
}
)

答案 1 :(得分:0)

尝试

const AppDrawerNavigator = createDrawerNavigator({
        Login:Login,
        Viatura:Login,
    }, {
            contentComponent: CustomDrawerComponent,
            drawerWidth: 300,
            contentOptions: {
                activeTintColor: 'orange'
            }
        })