Нарушение инварианта: не удалось найти «store» ни в контексте, ни в «Connect (App)» - PullRequest
0 голосов
/ 27 апреля 2018

Здравствуйте, я пытаюсь использовать избыточный код в приложении для реагирования и получаю ошибку, упомянутую в названии, в частности 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)". Я не уверен, в чем проблема, и хотя я следовал за подобными темами, пока ничего не работало.

Ниже - мой источник 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 голосов
/ 27 апреля 2018

Вы пытаетесь получить доступ к магазину в компоненте приложения, тогда как ваш провайдер находится внутри него. Таким образом, приложение на самом деле не получает магазин из контекста. Вам нужно обернуть приложение с провайдером, как

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>
}
0 голосов
/ 03 июля 2019

Поставщик должен обернуть компонент более высокого уровня. Компонент более низкого уровня или вложенный компонент, импортированный в компонент с поставщиком, должен иметь функцию подключения.

верхнего уровня (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);

Эта проблема относится только к реагирующим, потому что в реакции мы обычно заключаем приложение в index.js, что не относится к RN.

0 голосов
/ 27 апреля 2018

У вас есть App, завернутый в метод connect (), но вы создаете экземпляр компонента <Provider> в App. Я догадываюсь, что на данный момент нет store для подключения для доступа и дать App. Попробуйте удалить оператор connect и посмотреть, решит ли это вашу проблему.

У вас есть код, который зависит от данных из хранилища, я бы прокомментировал это на время, чтобы увидеть, работает ли вышеуказанное решение. Если это так, сделайте приложение простым компонентом, который стоит в магазине и переместите код для входа в систему и проверки пользователя на новый компонент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...