不变违规:无法在“连接(应用)”的上下文或道具中找到“存储”

时间:2018-04-27 13:10:16

标签: reactjs react-native redux react-redux

您好我正在尝试在react-native应用程序中使用redux,我收到标题中提到的错误,特别是Invariant Violation: Could not find "store" in either the context or props of "Connect(App)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(App)"。我不确定是什么问题,虽然我跟着类似的线程到目前为止没有任何工作。

Bellow是我的App.js来源

import React, { Component } from 'react';
import { Provider, connect } from 'react-redux';
import { Platform, StyleSheet, Text, View } from 'react-native';
import * as utils from './src/utils';
import store from './src/store';

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

class App extends React.Component {

    constructor(...args) {
        super(...args);
    }

    login({ username, password }) {

        let requestData = new FormData();

        requestData.append('username', username);
        requestData.append('password', password);

        console.log('[Login]: Attempt');
        console.log(JSON.stringify(requestData, null, 4));

        fetch('https://my-api.lab/user/login', {
            method: 'POST',
            body: requestData
        }).then(res => res.json()).then((json) => {

            console.log('[Login]: Response');
            console.log(JSON.stringify(json, null, 4));

            if (json.authenticated) {

                console.log('[Login]: Success');

                this.props.userLoginSuccess(json);

            } else {
                console.log('[Login]: Failure');
            }

        }).catch((err) => {

            console.log('[Login]: error');
            console.log(JSON.stringify(err, null, 4));

        });

    }

    componentDidMount() {

        console.log('App mounted!');

        this.login({
            username: 'asdf',
            password: 'asdf'
        });

    }

    render() {

        let username = Object.keys(this.props.user).length ? this.props.user.data.post.username : '';

        return (

            <Provider store={store}>

                <View style={styles.container}>
                    <Text style={styles.welcome}>
                        Welcome {username} to React Native!
                    </Text>
                </View>

            </Provider>

        );
    }
}

const mapStateToProps = (state) => {
    return {
        user: state.userReducer
    }
}

const mapDispatchToProps = (dispatch) => {

    return {

        userLoginSuccess: (user) => {

            dispatch({
                type: 'USER_LOGIN_SUCCESS',
                payload: user
            })

        },

        userLoginFailure: (user) => {

        }

    }

}

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

此处还有我的index.js文件

import { AppRegistry } from 'react-native';
import App from './App';

AppRegistry.registerComponent('pushNotificationsNative', () => App);

商店

import { createStore } from 'redux';
import rootReducer from '../reducers/index.js';

const store = createStore(
    rootReducer
);

export default store;

最后是一个简单的减速器

import deepExtend from 'deep-extend';

const initialState = {};

const userReducer = (state = initialState, action) => {

    switch (action.type) {

        case 'USER_LOGIN_SUCCESS': {
            return deepExtend({}, state, action.payload);
        }

        default: {
            return deepExtend({}, state);
        }

    }

}

export default userReducer;

3 个答案:

答案 0 :(得分:1)

您已将App包装在connect()方法中,但正在<Provider>中实例化App组件。我的预感是,目前没有store用于连接访问并提供给App。尝试删除connect语句,看看是否能解决您的问题。

你的代码依赖于来自商店的数据,我会暂时评论一下,看看上面的解决方案是否有效。如果确实如此,那么make app只是一个简单的组件,可以支持商店并移动代码进行登录并将用户检查到新组件。

答案 1 :(得分:1)

提供程序必须包装更高级别的组件。 下层组件或使用提供程序导入的嵌套组件应具有连接功能。

顶级(index.js):

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

高级组件(app.js):

const store = createStore(reducers);
const App = () => {
    return <Provider store={store}>
        <UI/>
    </Provider>;
};
export default App;

较低级别/嵌套的(ui.js)

const UI = () => {
return <View><Text>Hello</Text></View>;
};
export default connect()(UI);

此问题特定于react-native,因为在react中,我们通常将App包装在index.js中,而RN则不是这种情况。

答案 2 :(得分:0)

您正在尝试访问App组件中的商店,而您的提供商在其中进行了回访,而App并未真正从上下文中获取商店。您需要使用提供程序包装App,如

class App extends React.Component {

    constructor(...args) {
        super(...args);
    }

    login({ username, password }) {

        let requestData = new FormData();

        requestData.append('username', username);
        requestData.append('password', password);

        console.log('[Login]: Attempt');
        console.log(JSON.stringify(requestData, null, 4));

        fetch('https://my-api.lab/user/login', {
            method: 'POST',
            body: requestData
        }).then(res => res.json()).then((json) => {

            console.log('[Login]: Response');
            console.log(JSON.stringify(json, null, 4));

            if (json.authenticated) {

                console.log('[Login]: Success');

                this.props.userLoginSuccess(json);

            } else {
                console.log('[Login]: Failure');
            }

        }).catch((err) => {

            console.log('[Login]: error');
            console.log(JSON.stringify(err, null, 4));

        });

    }

    componentDidMount() {

        console.log('App mounted!');

        this.login({
            username: 'asdf',
            password: 'asdf'
        });

    }

    render() {

        let username = Object.keys(this.props.user).length ? this.props.user.data.post.username : '';

        return (
                <View style={styles.container}>
                    <Text style={styles.welcome}>
                        Welcome {username} to React Native!
                    </Text>
                </View>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        user: state.userReducer
    }
}

const mapDispatchToProps = (dispatch) => {

    return {

        userLoginSuccess: (user) => {

            dispatch({
                type: 'USER_LOGIN_SUCCESS',
                payload: user
            })

        },

        userLoginFailure: (user) => {

        }

    }

}

const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App);

export default const Root = () => {
    <Provider store={store}><ConnectedApp/></Provider>
}