ReduxForm 装饰器,弹出 create-react-app 后出现 no-class-assign 错误

Posted

技术标签:

【中文标题】ReduxForm 装饰器,弹出 create-react-app 后出现 no-class-assign 错误【英文标题】:ReduxForm decorator, no-class-assign error after ejecting create-react-app 【发布时间】:2017-07-14 09:22:15 【问题描述】:

我最近弹出了我的 create-react-app,我收到一个 ReduxForm 错误,阻止了 webpack 编译。这是错误:“错误'NewComplaintModal'是一个类无类分配”。它似乎与底部的 redux 表单装饰器相关联,但我在 redux-form 文档中找不到任何其他实现。知道如何解决这个问题吗?

import React,  Component  from 'react';
import  connect  from 'react-redux';
import  bindActionCreators  from 'redux';
import * as Actions from '../actions';
import  Field, reduxForm  from 'redux-form';
import DatePicker from "react-bootstrap-date-picker";

class NewComplaintModal extends Component 
  close() 
    this.props.actions.hideModal();
  

  handleFormSubmit(formProps) 
    this.props.actions.submitComplaint(formProps);
  

  render()
    const  handleSubmit  = this.props;

    const show = this.props.modalType ? true : false;

    const RenderDatePicker = (input, meta: touched, error ) => (
      <div>
        <DatePicker showClearButton=false ...input />
        touched && error && <span>error</span>
      </div>
    );

    return(
      <div>
        ...
      </div>
    )
  


NewComplaintModal = reduxForm(
  form: 'newComplaintModal'
)(NewComplaintModal);


function mapStateToProps(state) 
  return 
    modal: state.modal
  ;


function mapDispatchToProps(dispatch) 
  return 
    actions: bindActionCreators(Actions, dispatch)
  ;


export default connect(mapStateToProps, mapDispatchToProps)(NewComplaintModal)

【问题讨论】:

【参考方案1】:

首先,您要像这样声明一个名为 NewComplaintModal 的类

class NewComplaintModal extends Component 
  ...

然后,您正在处理您的NewComplaintModal,这是一个类声明,就像它是一个变量一样,如下所示:

NewComplaintModal = reduxForm(
  form: 'newComplaintModal'
)(NewComplaintModal);

这就是您看到特定错误的原因,即抱怨课程被重新分配。为了解决这个问题,我建议在 connect 之前跳过使用 reduxForm 装饰器的中间步骤,并使用装饰器语法将它们链接起来:

import React,  Component  from 'react';
import  connect  from 'react-redux';
import  bindActionCreators  from 'redux';
import * as Actions from '../actions';
import  Field, reduxForm  from 'redux-form';
import DatePicker from "react-bootstrap-date-picker";

export class NewComplaintModal extends Component 
  close() 
    this.props.actions.hideModal();
  

  handleFormSubmit(formProps) 
    this.props.actions.submitComplaint(formProps);
  

  render()
    const  handleSubmit  = this.props;

    const show = this.props.modalType ? true : false;

    const RenderDatePicker = (input, meta: touched, error ) => (
      <div>
        <DatePicker showClearButton=false ...input />
        touched && error && <span>error</span>
      </div>
    );

    return(
      <div>
        ...
      </div>
    )
  


function mapStateToProps(state) 
  return 
    modal: state.modal
  ;


function mapDispatchToProps(dispatch) 
  return 
    actions: bindActionCreators(Actions, dispatch)
  ;



// use decorators around an extension of your component
// to plug into redux and redux-form
@connect(mapStateToProps, mapDispatchToProps)
@reduxForm( form: 'newComplaintModal' )
export default class NewComplaintModalContainer extends NewComplaintModal 

如果你不想使用装饰器语法,你可以这样做:

export default connect(mapStateToProps, mapDispatchToProps)(
  reduxForm( form: 'newComplaintModal' )(
    NewComplaintModal
  )
)

这种方法基本上将您的组件与类似配置的元素(即与与应用程序状态交互相关的任何内容)隔离开来。

希望这会有所帮助!

【讨论】:

【参考方案2】:

@jakee 指出了您收到错误的原因。

你可以做的另一种方法是使用redux的compose方法。

import  compose  from 'redux';
...
export default compose(
  connect(mapStateToProps, mapDispatchToProps),
  reduxForm(...),
)(NewComplaintModal);

【讨论】:

【参考方案3】:

我找到了一个不太优雅的解决方案:代替未初始化的 NewComplaintModal,声明一个具有不同名称的新变量并将该变量传递给连接函数的返回值。

例如:

const NewComplaintModalTemp = reduxForm(
  form: 'newComplaintModal'
)(NewComplaintModal);

export default connect(mapStateToProps, mapDispatchToProps)(NewComplaintModalTemp)

如果有人有更好的解决方案或想分享任何其他相关信息以帮助解释为什么这是必要的,我们将不胜感激。

【讨论】:

以上是关于ReduxForm 装饰器,弹出 create-react-app 后出现 no-class-assign 错误的主要内容,如果未能解决你的问题,请参考以下文章

装饰器作为弹出窗口不起作用

设计模式:结构型-装饰器模式

是否可以将装饰器与 create-react-app 一起使用?

React中reduxForm表单编辑

Python装饰类中的方法和继承

使用酶测试ReduxForm