Javascript TypeError:_react2.default.PropTypes未定义

Javascript TypeError:_react2.default.PropTypes未定义,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我最近将我的项目升级为使用React 16.4.1,而不是15.2.1。 我有以下组件,它通过给我TypeError而中断:_react2.default.PropTypes是未定义的错误 import React, { Component } from 'react'; import { connect } from 'react-redux'; export default function (ComposedComponent) { class Authentication exte

我最近将我的项目升级为使用React 16.4.1,而不是15.2.1。 我有以下组件,它通过给我TypeError而中断:_react2.default.PropTypes是未定义的错误

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function (ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: React.PropTypes.object,
    }

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/login');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}
import React,{Component}来自'React';
从'react redux'导入{connect};
导出默认函数(ComposedComponent){
类身份验证扩展了组件{
静态上下文类型={
路由器:React.PropTypes.object,
}
组件willmount(){
如果(!this.props.authenticated){
this.context.router.push('/login');
}
}
组件将更新(下一步){
如果(!nextrops.authenticated){
this.context.router.push('/login');
}
}
render(){
返回;
}
}
函数MapStateTops(状态){
返回{authenticated:state.auth.authenticated};
}
返回连接(MapStateTops)(身份验证);
}
我将代码更改为以下内容:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'

export default function (ComposedComponent) {
  class Authentication extends Component {
    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/login');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  Authentication.propTypes = {
    router: PropTypes.object
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'

export default function (ComposedComponent) {
  class Authentication extends Component {
    static propTypes = {
      router: PropTypes.object
    }

    componentDidMount() {
      if (!this.props.authenticated) {
        const {router} = this.props;
        router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        const {router} = this.props;
        router.push('/login');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return withRouter(connect(mapStateToProps)(Authentication));
}
import React,{Component}来自“React”
从“react redux”导入{connect}
从“道具类型”导入道具类型
导出默认函数(ComposedComponent){
类身份验证扩展了组件{
组件willmount(){
如果(!this.props.authenticated){
this.context.router.push('/login');
}
}
组件将更新(下一步){
如果(!nextrops.authenticated){
this.context.router.push('/login');
}
}
render(){
返回;
}
}
身份验证.propTypes={
路由器:PropTypes.object
}
函数MapStateTops(状态){
返回{authenticated:state.auth.authenticated};
}
返回连接(MapStateTops)(身份验证);
}

但现在我得到了TypeError:this.context.router未定义。有人能给我解释一下或指出我做错了什么吗?

从react 15.5开始,PropTypes库就在它自己的包中,
prop types

解决方案:

1.在项目中安装道具类型包:

npm i prop-types --save
2.根据需要导入并使用它

import PropTypes from 'prop-types';
请注意,这也意味着您可能需要将任何依赖PropTypes的库升级到其post react 15.5版本。在某些情况下,某些库可能没有可用的升级,因此您需要打开拉取请求。现在,您已经掌握了解决此问题所需的所有信息。这并不容易,但如果你想要react 16的功能,它是非常值得的。我做了升级,花了大约2到3个小时让一切正常工作

请在此处阅读更多信息:
多亏了罗斯·艾伦的评论,我最终使用了withRouter。 我目前拥有的代码如下:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'

export default function (ComposedComponent) {
  class Authentication extends Component {
    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/login');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  Authentication.propTypes = {
    router: PropTypes.object
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'

export default function (ComposedComponent) {
  class Authentication extends Component {
    static propTypes = {
      router: PropTypes.object
    }

    componentDidMount() {
      if (!this.props.authenticated) {
        const {router} = this.props;
        router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        const {router} = this.props;
        router.push('/login');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return withRouter(connect(mapStateToProps)(Authentication));
}
import React,{Component}来自“React”
从“react redux”导入{connect}
从“道具类型”导入道具类型
从“react router”导入{withRouter}
导出默认函数(ComposedComponent){
类身份验证扩展了组件{
静态类型={
路由器:PropTypes.object
}
componentDidMount(){
如果(!this.props.authenticated){
const{router}=this.props;
router.push('/login');
}
}
组件将更新(下一步){
如果(!nextrops.authenticated){
const{router}=this.props;
router.push('/login');
}
}
render(){
返回;
}
}
函数MapStateTops(状态){
返回{authenticated:state.auth.authenticated};
}
使用路由器返回(连接(MapStateTops)(身份验证));
}

它可以工作,可能还有更多的增强。

您在第二个代码片段中将
contextTypes
更改为
propTypes
。刚刚再次更改了代码,但我仍然收到相同的错误。你能详细谈谈你的评论吗?@AlessandroCali道具类型在react 16中被转移到一个单独的项目中。如果您非常依赖它,您将使用
npm安装道具类型安装它
,然后像导入“道具类型”中的
导入道具类型一样导入它并根据需要使用它。请参阅此处了解更多信息->@r3wt,是的,我已完成以下操作。我已经有了一段时间的代码,今天我再次触摸它,打算一次性修复它。我显然被困在某个地方,不知道确切的位置。希望已经这么做的人能帮我解决我的问题你也升级了react路由器吗?我建议将他们的
用于路由器
高阶组件,而不是尝试使用
this.context.router
:因此,我尝试了一些方法。都不成功。我已经将我的问题更新为我拥有的最新代码,但我仍然感到困惑。既然您已经经历了这一过程,您将如何更改我的原始代码,使其成为React 16的投诉?