javascript - ReactJs/Redux 不变违规 : Could not find "store" in either the context or props of "Connect(LoginContainer)"

标签 javascript reactjs redux react-redux jestjs

不确定为什么会出现此错误,这是在我添加 connect 时发生的来自 redux到我的登录组件,这样我就可以连接我的 store .

FAIL src/components/auth/Login.test.js

● Test suite failed to run

Invariant Violation: Could not find "store" in either the context or props of "Connect(LoginContainer)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(LoginContainer)".

enter image description here

索引.js

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from "react-redux"
import { createCommonStore } from "./store";
import App from './App'
import css from './manage2.scss'

const store = createCommonStore();
const element = document.getElementById('manage2');
console.log("Index.js Default store", store.getState());

ReactDOM.render(
    <Provider store={store}>  // <-- store added here
        <App />
    </Provider>, element);

商店.js

import React from "react"
import { applyMiddleware, combineReducers, compose, createStore} from "redux"
import thunk from "redux-thunk"
import { userReducer } from "./reducers/UserReducer"
import { authReducer } from "./reducers/AuthReducer"

export const createCommonStore = (trackStore=false) => {
    const reducers = combineReducers({
        user: userReducer,
        user: authReducer
    });

    //noinspection JSUnresolvedVariable
    const store = createStore(reducers,
        compose(
            applyMiddleware(thunk),
            window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
        )
    );

    if (trackStore) {
        store.subscribe((() => {
            console.log("  store changed", store.getState());
        }));
    }

    return store;
};

应用程序.js

import React from 'react'
import { BrowserRouter as Router } from 'react-router-dom'
import Routes from './components/Routes'
const supportsHistory = "pushState" in window.history

export default class App extends React.Component {
    render() {
        return (
            <Router forceRefresh={!supportsHistory}>
                <Routes />
            </Router>
        );
    }
}

路由.js

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import LoginContainer from './auth/Login'
import Dashboard from './Dashboard'
import NoMatch from './NoMatch'

const Routes = () => {
    return (
        <Switch>
            <Route exact={ true } path="/" component={ LoginContainer }/>
            <Route path="/dashboard" component={ Dashboard }/>
            <Route component={ NoMatch } />
        </Switch>
    );
}

export default Routes

最后是 Login.js(为简洁起见删除了代码

import React from 'react'
import { connect } from "react-redux"
import { bindActionCreators } from 'redux'; 
import { setCurrentUser } from '../../actions/authActions'
import * as api from '../../services/api'

const mapDispatchToProps = (dispatch) => {
    console.log('mapDispatchToProps', dispatch);
    return {
        setUser: (user) => {
            bindActionCreators(setCurrentUser(user), dispatch)
        }
    }
}

class LoginContainer extends React.Component {
    constructor(props) {
        super(props)

        this.state = {};

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(e) {
    }

    handleSubmit(e) {
    }

    render() {
        return (
            <div className="app-bg">
                ...
            </div>
        )
    }
}

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

登录.test

import React from 'react'
import ReactTestUtils from 'react-dom/test-utils'
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
import Login from './Login'
import Notification from '../common/Notification'

const loginComponent = shallow(<Login />);
const fakeEvent = { preventDefault: () => '' };

describe('<Login /> component', () => {
    it('should render', () => {
        const tree = toJson(loginComponent);
        expect(tree).toMatchSnapshot();
    });

    it('should render the Notification component if state.error is true', () => {
        loginComponent.setState({ error: true });
        expect(loginComponent.find(Notification).length).toBe(1);
    });
});

describe('User Login', () => {
    it('should fail if no credentials are provided', () => {
        expect(loginComponent.find('.form-login').length).toBe(1);
        loginComponent.find('.form-login').simulate('submit', fakeEvent);
        expect(loginComponent.find(Notification).length).toBe(1);
        const notificationComponent = shallow(<Notification message={ missingLogin }/>);
        expect(notificationComponent.text()).toEqual('Please fill out both username and password.');
    });

    it('input fields should be filled correctly', () => {
        const credentials = { username: 'leongaban', password: 'testpass' };
        expect(loginComponent.find('#input-auth-username').length).toBe(1);

        const usernameInput = loginComponent.find('#input-auth-username');
        usernameInput.value = credentials.username;
        expect(usernameInput.value).toBe('leongaban');

        const passwordInput = loginComponent.find('#input-auth-password');
        passwordInput.value = credentials.password;
        expect(passwordInput.value).toBe('testpass');
    });
});

你觉得哪里不对?

最佳答案

Redux 建议导出未连接的组件进行单元测试。查看他们的 docs .

在 login.js 中:

// Named export for tests
export class LoginContainer extends React.Component {
}

// Default export
export default connect(null, mapDispatchToProps)(LoginContainer); 

在你的测试中:

// Import the named export, which has not gone through the connect function
import { LoginContainer as Login } from './Login';

然后您可以在组件上指定直接来自商店的任何 Prop 。

关于javascript - ReactJs/Redux 不变违规 : Could not find "store" in either the context or props of "Connect(LoginContainer)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44458605/

相关文章:

javascript - Passport 认证后无法找回用户

javascript - 递归函数不返回对象值的总和

javascript - React setState 不重新渲染

javascript - 为什么我的 React Accordion 动画不起作用?

reactjs - 输入 { child : Element; } has no properties in common with type IntrinsicAttributes

javascript - 使用 redux 有什么好处?

javascript - 添加到购物车时隐藏产品,点击 woocommerce

javascript - 使用 javascript 技巧编辑网页 - 如何 "unedit"?

react-router - react 路由器监听获取参数

javascript - 将 React 本地状态与 Redux 全局状态相结合