react-redux - 来自mapDispatchToProps的道具未定义PropTypes

时间:2017-10-10 23:33:17

标签: reactjs redux undefined

我一直试图解决这个问题几个小时了。

我导入为userActionCreators的功能失败Proptypes.func.isRequired

这是prop-types给我的错误消息: -

  

警告:道具类型失败:道具authUser被标记为必需   在Authenticate中,但其值为undefined

在我的容器中: -

import React from 'react'
import PropTypes from 'prop-types';
import {Authenticate} from '_components/'
import auth from '_helpers/auth'
import { connect } from 'react-redux'
import * as userActionCreators from '_redux/modules/users'
import { bindActionCreators } from 'redux'

class AuthenticateContainer extends React.Component {

  render() {

const handleAuth = () => {

  this.props.fetchingUser()
  auth().then((user) => {
    this.props.fetchingUserSuccess(user.uid, user, Date.now())
    this.props.authUser(user.id)
  })
  .catch((error) => this.props.fetchingUserFailure(error) )
}

    return (
      <Authenticate
        isFetching={this.props.isFetching}
        error={this.props.error}
        onAuth={handleAuth}
      />
    );
  }
}

Authenticate.propTypes = {
  error: PropTypes.string.isRequired,
  isFetching: PropTypes.bool.isRequired,
  authUser: PropTypes.func.isRequired,
  fetchingUser: PropTypes.func.isRequired,
  fetchingUserFailure: PropTypes.func.isRequired,
  fetchingUserSuccess: PropTypes.func.isRequired,
};

const mapStateToProps = (state) => {
  return {
    isFetching: state.isFetching,
    error: state.error
  }
}

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(userActionCreators, dispatch)
}

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

验证组件: -

import React from 'react'
import PropTypes from 'prop-types';
import {FacebookAuthButton} from '_components/'

const Authenticate = ({error = 'this is an error', isFetching, onAuth}) => {
  return(
    <div className='centeredContainer'>
      <h1 className='largeHeader'>
        {'Authenticate'}
      </h1>
      <FacebookAuthButton isFetching={isFetching} onAuth={onAuth}/>
      {error ? <p className='errorMsg' >{error}</p> : null}
    </div>
  )
}

Authenticate.propTypes = {
  error: PropTypes.string.isRequired,
  isFetching: PropTypes.bool.isRequired,
  onAuth: PropTypes.func.isRequired
};

export default Authenticate

用户模块: -

const AUTH_USER = 'AUTH_USER'
const UNAUTH_USER = 'UNAUTH_USER'
const FETCHING_USER = 'FETCHING_USER'
const FETCHING_USER_FAILURE = 'FETCHING_USER_FAILURE'
const FETCHING_USER_SUCCESS = 'FETCHING_USER_SUCCESS'

export const authUser = (uid) => {
  return {
    type: AUTH_USER,
    uid
  }
}

const unAuthUser = () => {
  return {
    type: UNAUTH_USER
  }
}

export const fetchingUser = () => {
  return {
    type: FETCHING_USER
  }
}

export const fetchingUserFailure = (error) => {
  return {
    type: FETCHING_USER_FAILURE,
    error: 'Error fetching user.'
  }
}

export const fetchingUserSuccess = (uid, user, timestamp) => {
  return {
    type: FETCHING_USER_SUCCESS,
    uid,
    user,
    timestamp,
  }
}

// Reducers

const initialUserState = {
  lastUpdated: 0,
  info: {
    name: '',
    uid: '',
    avatar: '',
  },
}

const user = (state = initialUserState, action) => {
  switch (action.type) {
    case FETCHING_USER_SUCCESS :
      return {
        ...state,
        info: action.user,
        lastUpdated: action.timestamp,
      }
    default :
      return state
  }
}

const initialState = {
  isFetching: false,
  error: '',
  isAuthed: false,
  authedId: '',
}

export const users = (state = initialState, action) => {
  switch (action.type) {
    case AUTH_USER :
      return {
        ...state,
        isAuthed: true,
        authedId: action.uid,
      }
    case UNAUTH_USER :
      return {
        ...state,
        isAuthed: false,
        authedId: '',
      }
    case FETCHING_USER:
      return {
        ...state,
        isFetching: true,
      }
    case FETCHING_USER_FAILURE:
      return {
        ...state,
        isFetching: false,
        error: action.error,
      }
    case FETCHING_USER_SUCCESS:
      return action.user === null
        ? {
          ...state,
          isFetching: false,
          error: '',
        }
        : {
          ...state,
          isFetching: false,
          error: '',
          [action.uid]: user(state[action.uid], action),
        }
    default :
      return state
  }
}

1 个答案:

答案 0 :(得分:2)

您是否在容器组件中的错误对象上设置了proptypes?

Authenticate.propTypes应为AuthenticateContainer.propTypes

AuthenticateContainer.propTypes = {
  error: PropTypes.string.isRequired,
  isFetching: PropTypes.bool.isRequired,
  authUser: PropTypes.func.isRequired,
  fetchingUser: PropTypes.func.isRequired,
  fetchingUserFailure: PropTypes.func.isRequired,
  fetchingUserSuccess: PropTypes.func.isRequired,
};

避免此问题的一个好方法是将您的proptypes定义为类中的静态:

class AuthenticateContainer extends React.Component {

  static propTypes = {
    error: PropTypes.string.isRequired,
    isFetching: PropTypes.bool.isRequired,
    authUser: PropTypes.func.isRequired,
    fetchingUser: PropTypes.func.isRequired,
    fetchingUserFailure: PropTypes.func.isRequired,
    fetchingUserSuccess: PropTypes.func.isRequired
  };

  // ...etc
}