2017-09-17 96 views
0

我收到错误/警告“失败的道具类型:道具loggedApp中被标记为需要,但在App中它的值为undefined”。我无法弄清楚为什么它没有从商店获得价值。使用mapStateToProps()连接到商店

index.js

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import PropTypes from 'prop-types'; 
import {BrowserRouter, Switch, Route, Redirect} from 'react-router-dom'; 
import {Provider, connect} from 'react-redux'; 
import store from './store/store'; 

import Signup from './components/Signup'; 
import Home from './components/Home'; 

class App extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      logged: this.props.logged 
     }; 
    } 

    render() { 
     return (
      <Provider store={store}> 
       <BrowserRouter> 
        <Switch> 
         <Route exact path="/signup" component={Signup}/>       
         <Route exact path="/home" component={Home}/>        
         <Route exact path="/" render={() => (
          this.state.logged ? 
           <Redirect to="/home" push/> : <Redirect to="/signup" push/> 
         )}/> 
         <Redirect to="/"/> 
        </Switch> 
       </BrowserRouter> 
      </Provider> 
     ); 

    } 
} 

App.propTypes = { 
    logged: PropTypes.bool.isRequired 
}; 


const stateToProps = (state) => ({ 
    logged: state.loggedUserState.logged 
}); 

connect(stateToProps)(App); 

ReactDOM.render(<App/>, document.getElementById('root')); 

loggedUserReducer.js

const initialState = { 
    pending: true, 
    logged: false 
}; 

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

    if (action.type === 'GET_LOGGED_USER') { 
     return Object.assign({}, state, { 
      pending: false 
     }); 
    } 

    return state; 
}; 

export default loggedUserReducer; 

store.js

import { createStore, combineReducers } from 'redux'; 
import loggedUserReducer from '../reducers/loggedUserReducer'; 

const reducers = combineReducers({ 
    loggedUserState: loggedUserReducer 
}); 

const store = createStore(reducers); 

export default store; 

回答

2

代码

//- Everything else.. 
 

 
connect(stateToProps)(App); //- Assign App here! 
 

 
ReactDOM.render(<App/>, document.getElementById('root'));

你忘了应用程序分配给您刚刚初始化connect版应用程序。

改为此。

//- Everything else ... 
 

 
App.propTypes = { 
 
    logged: PropTypes.bool.isRequired 
 
}; 
 

 

 
const stateToProps = (state) => ({ 
 
    logged: state.loggedUserState.logged 
 
}); 
 

 
const ConnectedApp = connect(stateToProps)(App); 
 

 
ReactDOM.render(<ConnectedApp/>, document.getElementById('root'));

装饰!

如果你有装修enabled你也可以做。

@connect(state => ({ 
 
    logged: state.loggedUserState.logged 
 
}) 
 
class App extends React.Component { 
 

 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      logged: this.props.logged 
 
     }; 
 
    } 
 

 
    render() { 
 
     return (
 
      <Provider store={store}> 
 
       <BrowserRouter> 
 
        <Switch> 
 
         <Route exact path="/signup" component={Signup}/>       
 
         <Route exact path="/home" component={Home}/>        
 
         <Route exact path="/" render={() => (
 
          this.state.logged ? 
 
           <Redirect to="/home" push/> : <Redirect to="/signup" push/> 
 
         )}/> 
 
         <Redirect to="/"/> 
 
        </Switch> 
 
       </BrowserRouter> 
 
      </Provider> 
 
     ); 
 

 
    } 
 
} 
 

 
App.propTypes = { 
 
    logged: PropTypes.bool.isRequired 
 
}; 
 

 
ReactDOM.render(<App/>, document.getElementById('root'));

约装饰更多见:this article

更多关于反应/ REDUX看到this

警告有关从在下面的评论部分@markerikson装饰

使用装饰器和这样的proptypes仍然会导致 警告。这是因为您将proptypes分配给由连接生成的包装 组件,而从mapState 返回的数据作为道具给予包装组件。这是其中一个原因 为什么我们建议不要使用connect作为装饰器。

+0

非常有帮助。谢谢。 –

+0

我明白,谢谢。 – ArchNoob

+0

从概念上讲,它是有道理的......它仍然给ESLint错误“'App'是一个没有类别分配的类”。我正在通过它。 –