在“ Connect(MyComponent)”的上下文中找不到“存储”。可以将根组件包装在<Provider>中,

时间:2019-07-14 18:03:03

标签: reactjs react-redux react-router-v4

我正在将React-Redux设置到我的Web应用程序中,在“ Connect(Register)”的上下文中我一直找不到“存储”。

我想也许我必须通过在[[2]] store.js中创建的商店,并且该商店可以工作,但是我没有看到它以这种方式在线运行,当我尝试使用redux DevTools时,它一直保持显示未找到任何商店。

我认为connect()的目的是包装组件并通过mapStateToProps访问redux中的全局状态。如果有人可以将我指向正确的方向,或者可以解释为什么我会收到此错误,那就太好了!

我尝试过的事情:

  1. 因为我有一个容器组件LoginContainer.js(我可以通过connect()(LoginContainer访问),所以我想我可以在这里访问状态并将道具传递给register.js组件,然后传播状态变化。

  2. 我一直在考虑将register.js更改为功能组件,因为这可能会在某种程度上影响它?

我一直在阅读有关上下文的信息,以及如何通过在index.js上使用<Provider store={store}>来允许它通过connect(mapState,MapDispach)(Component)来访问Redux存储,但是我仍然无法区分其方式或时间我正在失去提供者的上下文。

//index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux"
import { BrowserRouter, Route } from "react-router-dom";
import store from "./store";

ReactDOM.render(
  <BrowserRouter>
    <Provider store={store}>
      <App />
    </Provider>
  </BrowserRouter>,
  document.getElementById("root")
);

// App.js 

import React, { Component } from "react";
import {
  Route,
  Switch
} from "react-router-dom";
import LoginContainer from "./containers/login";
class App extends Component{
  render() {
    return (
          <div className="App">
          <header className="App-header">
          <Switch>
          <Route path='/login' component={LoginContainer} />
          </Switch>
          </header>
          </div>

    );
  }
}

export default App;


// LoginContainer.js 
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Register from "../componets/Registration/register";
import Login from "../componets/Login/login";
import { withRouter } from "react-router-dom";
import { Input, Button } from "semantic-ui-react";
import { connect } from "react-redux";
import store from "../store";
class LoginContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
        //some local UI states
    };
  }
  render() {
    return (
      <div>
        <div className="ToggleContainer">
          <div className={"toggle"}>
            <Button.Group>
              <Button
                onClick={this.registerHandler}
                positive={this.state.registerOn}
              >
                SignUp
              </Button>
              <Button.Or />
              <Button onClick={this.loginHandler} positive={this.state.loginOn}>
                Login
              </Button>
            </Button.Group>
          </div>
 <Provider store = {store}> <Register {...this.props} /> </Provider> // [[6]], uncommented [[4]] works but is it different than method [[1]]?
 //  <Register{...this.props} /> // [[2]] cannot connect to store
       // <Register store={store} {...this.props} />} [[1]] can connect store via directly sending store //
        </div>
      </div>
    );
  }
}



  // ReactDOM.render(<LoginContainer />,  document.getElementById("root")); [[answer]] removing this fixed the problem

const mapStateToProps = state => {
  return {
    loggedIn: state.registration.isLoggedIn
  };
};

const mapDisptachToProps = dispatch => ({
  registerUser: id => dispatch({ type: "SIGN_IN" })
});
export default withRouter(
  connect(
    mapStateToProps,
    mapDisptachToProps
  )(LoginContainer)
);



//components/register.js

import React, { Component } from "react";
import { Input, Button } from "semantic-ui-react";

import { connect } from "react-redux";

class Register extends Component {
  constructor(props) {
    super(props);
    // Local State

  }
   const check() {
   let userData: User;
    if (validEmail(this.state.email)) {
      userData = {
       //data 
      };

     let user = await this.handleSignUp(userData);
       const res = JSON.parse(user);

        if (res.message === "Success") {
          alert('Account success')
        }
      if(typeof user === 'string'){
         user =JSON.parse(user)
      }
    } else {
      this.setState({ hiddenErrorMessage: false });
    }
    this.props.registerUser(userData);

    // func: returns true if it is valid, o.w. false
    function validEmail(email) {

    }
  };
  //handlers()

  render() {
    return (
      // eslint-disable-next-line react/jsx-filename-extension
      <div>
        <Input
          className="customInput"
          onChange={this.handleEmail}
          placeholder="Email"
        />
        <Input
          className="customInput"
          onChange={this.handlePassword}
          placeholder="Password"
          type="password"
        />
        <br />
        <Button
          size="big"
          className="customButton"
          onClick={this.checkUserInput}
        >
          Sign up
        </Button>
        <p>
          <span hidden={this.state.hiddenErrorMessage}>
            Invalid Email/Passoword
          </span>
        </p>
      </div>
    );
  }
}

const mapStateToProps = (state) => {

 return {
   loggedIn:state.registration.isLoggedIn
 }
};

const mapDisptachToProps = dispatch => ({
  registerUser: id =>  dispatch({ type: "SIGN_IN" }) // return dispatch
});

export default Register // [[3]] Works as expected
// export default connect( [[4]] Could not find "store" in the context of "Connect(Register)". Either wrap the root component in a <Provider> Error
//   mapStateToProps,
//   mapDisptachToProps
// )(Register);


//store.js 

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

export default createStore(rootReducer);


//reducers/index.js

import { combineReducers } from "redux";
import registration from "./registration";

export default combineReducers({ registration });

//actionType.js
const SIGN_IN = 'SIGN_IN';

export { SIGN_IN };
//reducers/registration.js

const initialState = {
  isAuthenticated: false,
  isLoggedIn: false,
  isLoggedOut: false,
  userId : ''
};

export default (state = initialState, action) => {
  if (action.type === "SIGN_IN") {
    return { ...state, isLoggedIn: true };
  }
  if (action.type === "SIGN_OUT") {
    return { ...state, isLoggedOut: true };
  }
  return state;
};

1 个答案:

答案 0 :(得分:1)

此问题的解决方案是从 <Drawer initial navigationBarStyle={Styles.navigationBarStyle} key="drawer" contentComponent={DrawerMenu} drawerWidth={220} drawerIcon={<Icon name='menu' color={Colors.black} size={30} style={{marginTop: Platform.OS === 'ios' ? -5 : 0}} onPress={this.handleDrawerIconPress}/>} title='main Title' rightTitle=' ' > <Tabs initial tabBarPosition="top" key="tabbar" swipeEnabled showLabel={false} activeBackgroundColor={Colors.pink} activeTintColor={Colors.pink} inActiveTintColor={Colors.black} inactiveBackgroundColor={Colors.black} tabBarStyle={Styles.tabBar} indicatorStyle={Styles.indicatorStyle} iconStyle={Styles.iconStyle} showIcon={true} > <Scene initial key="home" component={Home} icon={TabsIcon} title="HOME" iconName='home' hideNavBar /> <Scene key="categories" component={Categories} title="CATEGORIES" icon={TabsIcon} iconName='categories' hideNavBar /> <Scene key="success" component={SuccessStories} title="SUCCESS STORIES" icon={TabsIcon} iconName='success-stories' hideNavBar /> </Tabs> </Drawer> 中删除下一个代码:

LogainContainer