2016-05-05 26 views
8

Tôi đã thực hiện một thành phần với một cửa hàng sử dụng phản ứng, redux và phản ứng-redux. gói mã được thực hiện bằng gói web. (Vui lòng kiểm tra các mã được đính kèm bên dưới)Lỗi khi sử dụng thành phần được thực hiện với phản ứng, redux và phản ứng-redux và xây dựng với webpack trong ứng dụng phản ứng

khi tôi muốn sử dụng thành phần xây dựng webpack bên trong một dự án phản ứng khác, tôi phải đối mặt với các vấn đề sau.

  • Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).

  • Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Sau đó, tôi tiếp tục và làm việc sửa đổi sau trong mã này, trước đó tôi đã có một nhiệm vụ destructuring như dưới đây cho kết nốibindActionCreators

import {connect} from 'react-redux'; 
 
import {bindActionCreators} from 'redux'; 
 
import actions from '../app/redux/actions';

Sau đó tôi thay đổi nó như dưới đây, bằng cách loại bỏ các dấu ngoặc nhọn xung quanh kết nối và bindActionCreators

import React from 'react'; 
 

 
import connect from 'react-redux'; 
 
import bindActionCreators from 'redux'; 
 
import actions from '../app/redux/actions'; 
 

 
import postal from 'postal'; 
 

 
const channel = postal.channel("msplayer"); 
 

 
class Player extends React.Component {

Nhưng sau đó tôi đang phải đối mặt với lỗi dưới đây, như tôi đoán đây là một cái gì đó để làm với babel transpiling ES6 để ES5, nhưng không chắc chắn những bước để làm theo để giải quyết này, muốn nhận được một câu trả lời hoặc một số gợi ý để có được điều này giải quyết?

  • Uncaught TypeError: (0 , _reactRedux2.default) is not a function

  • Uncaught TypeError: Cannot read property 'PlayerWrapper' of undefined

mã thành phần

import React from 'react'; 
 

 
import {connect} from 'react-redux'; 
 
import {bindActionCreators} from 'redux'; 
 
import actions from '../app/redux/actions'; 
 

 
import postal from 'postal'; 
 

 
const channel = postal.channel("msplayer"); 
 

 
class Player extends React.Component { 
 

 

 
    constructor() { 
 
     super(); 
 
     this.state = { 
 
      userData: {}, 
 
      uiStates: { 
 
       panelClosed: true, 
 
       submissionSelected: false 
 
      }, 
 
      selectedSubmission: {} 
 
     }; 
 
     this.subSelectChannel = null; 
 
     this.tabSelectChannel = null; 
 
    } 
 

 

 
    componentWillMount() { 
 
     require('!style!css!../app/styles/player.css'); 
 
    } 
 

 
    componentDidMount() { 
 
     var _that = this; 
 
     var _msData = { 
 
      piToken: this.props.piToken, 
 
      sectionId: this.props.sectionId, 
 
      assignmentId: this.props.assignmentId, 
 
      userId: this.props.userId 
 
     }; 
 

 
     this.props.actions.getAssignmentData(msData); 
 
     this.props.actions.getPeerSubmissionData(msData); 
 

 
     this.subSelectChannel = channel.subscribe("submission.selected", function (data, envelope) { 
 
      _that.setState({ 
 
        uiStates: Object.assign({}, _that.state.uiStates, { 
 
         "submissionSelected": true 
 
        }) 
 
       } 
 
      ); 
 
      _that.setState({ 
 
        selectedSubmission: data.submission 
 
       } 
 
      ); 
 
     }); 
 

 
     this.tabSelectChannel = channel.subscribe("tab.selected", function (data, envelope) { 
 
      if (data.submitted) { 
 
       _that.showSubmissionDetailPanel(data.data); 
 
      } else { 
 
       _that.hideSubmissionDetailPanel() 
 
      } 
 
     }); 
 
    } 
 

 
    closePanel() { 
 

 
     postal.publish({ 
 
      channel: "notifier", 
 
      topic: "notifier.notify", 
 
      data: { 
 
       type: "warning", 
 
       message: "warning message" 
 
      } 
 
     }); 
 

 

 
     if (this.state.uiStates.panelClosed) { 
 

 
      this.setState({ 
 
        uiStates: Object.assign({}, this.state.uiStates, { 
 
         "panelClosed": false 
 
        }) 
 
       } 
 
      ); 
 
     } else { 
 

 

 
      postal.publish({ 
 
       channel: "msplayer", 
 
       topic: "close.selected", 
 
       data: {} 
 
      }); 
 

 
      this.setState({ 
 
        uiStates: Object.assign({}, this.state.uiStates, { 
 
         "panelClosed": true, 
 
         "submissionSelected": false 
 
        }) 
 
       } 
 
      ); 
 
     } 
 
    } 
 

 

 
    hideSubmissionDetailPanel() { 
 
     console.log("inside hide submission panel"); 
 
     this.setState({ 
 
       uiStates: Object.assign({}, this.state.uiStates, { 
 
        "submissionSelected": false 
 
       }) 
 
      } 
 
     ); 
 
    }; 
 

 
    showSubmissionDetailPanel(data) { 
 
     console.log("inside show submission panel"); 
 
     this.setState({ 
 
       uiStates: Object.assign({}, this.state.uiStates, { 
 
        "submissionSelected": true 
 
       }) 
 
      } 
 
     ); 
 

 
     this.setState({ 
 
      selectedSubmission: data 
 
     }); 
 
    }; 
 

 

 
    loadUserAssignmentData(submission) { 
 

 
     this.setState({ 
 
       uiStates: Object.assign({}, this.state.uiStates, { 
 
        "submissionSelected": true 
 
       }) 
 
      } 
 
     ); 
 

 
     postal.publish({ 
 
      channel: "msplayer", 
 
      topic: "submission.selected", 
 
      data: { 
 
       submission: submission 
 
      } 
 
     }); 
 

 
    } 
 

 
    componentWillUnmount() { 
 
     postal.unsubscribe(this.subSelectChannel); 
 
     postal.unsubscribe(this.tabSelectChannel); 
 
    } 
 

 
    render() { 
 

 
     var _that = this; 
 
     var _submittedKey = 0; 
 
     var _unsubmittedKey = 0; 
 
     return (
 
      <div className="player-container col-sm-12"> 
 
       <div className="row"> 
 
       </div> 
 
       <div className="row"> 
 
        <div className={_that.state.uiStates.panelClosed?"col-sm-12":"col-sm-8"}> 
 
         <div className="top-actions-panel"> 
 
          <div className="pull-right"> 
 

 
          </div> 
 

 

 
         </div> 
 
         <div className="common-view"> 
 
          <div className="breadcrumb-panel"> 
 
           <ol className="breadcrumb arrow-left"> 
 
            <li><a href="#">Communication 220</a></li> 
 
            <li className="active">TED Topics for an Informative Speech</li> 
 
           </ol> 
 
          </div> 
 
          <div className="description-panel"> 
 
           <p className="title"> 
 
            <b>Title</b>: 
 
            <span>{_that.props.assignment.title}</span> 
 
           </p> 
 
           <p className="dueDates font-light"> 
 
            <b>Due </b>:<span>{_that.props.assignment.startDate}</span> 
 
            <b> - </b><span>{_that.props.assignment.endDate}</span> 
 
           </p> 
 
           <p> 
 
            <b>Learning Objective: </b> 
 
            <span>{_that.props.assignment.learningObjective}</span> 
 
           </p> 
 
           <p> 
 
            <b>Description: </b> 
 
            <span> 
 
             {_that.props.assignment.description} 
 
            </span> 
 
           </p> 
 
          </div> 
 

 
          <div 
 
           className={_that.state.uiStates.submissionSelected?"row submission-info col-sm-12":"hidden"}> 
 
           <div> 
 
            <span className="student-avatar"> 
 
             <img 
 
              src={(_that.state.selectedSubmission && _that.state.selectedSubmission.userDetails && _that.state.selectedSubmission.userDetails.avatar && _that.state.selectedSubmission.userDetails.avatar!=="")?_that.state.selectedSubmission.userDetails.avatar:"../app/images/avatar.svg"}/> 
 
            </span> 
 

 
            <p> 
 
             <b> <span 
 
              className="font-light mediaTile"><strong>{(_that.state.selectedSubmission.title && _that.state.selectedSubmission.title !== null && _that.state.selectedSubmission.title !== "") ? _that.state.selectedSubmission.title : "."}</strong></span> 
 
             </b> 
 
            </p> 
 
            <br/> 
 
            <p> 
 
             <span 
 
              className="font-light ">{(_that.state.selectedSubmission.description && _that.state.selectedSubmission.description !== null && _that.state.selectedSubmission.description !== "") ? _that.state.selectedSubmission.description : "."}</span> 
 
            </p> 
 
           </div> 
 
          </div> 
 

 
          <div className="common-functionality-panel col-sm-12"> 
 
          </div> 
 
         </div> 
 
        </div> 
 
        <div 
 
         className={_that.state.uiStates.panelClosed?"hidden":"col-sm-4 no-padding peer-review-panel"}> 
 

 
         <div className="review-section"> 
 
          <button className="btn btn-link pull-left close-panel" 
 
            onClick={_that.closePanel.bind(_that)}> 
 
           <span className="reader-only">Close Student Submission Panel</span> 
 
           <i className="fa fa-times"></i> 
 
          </button> 
 

 
          <div className="submission-tabs"> 
 
          </div> 
 
         </div> 
 
        </div> 
 
       </div> 
 
      </div> 
 
     ) 
 
    } 
 

 
} 
 

 
function mapStateToProps(state) { 
 
    return state 
 
} 
 

 
function mapDispatchToProps(dispatch) { 
 
    return { 
 
     actions: bindActionCreators(actions, dispatch) 
 
    } 
 
} 
 

 
export default connect(mapStateToProps, mapDispatchToProps)(Player)

thành phần mã wrapper

import React from 'react'; 
 
import Player from './app'; 
 

 
import bb from './redux/store' 
 
import Provider from 'react-redux'; 
 

 
class PlayerWrapper extends React.Component { 
 

 

 
    constructor(props) { 
 
     super(props); 
 
    } 
 

 
    render() { 
 
     return (
 
      <Provider store={bb.store}><Player piToken={this.props.piToken} sectionId={this.props.sectionId} 
 
               assignmentId={this.props.assignmentId} 
 
               userId={this.props.userId}/></Provider> 
 
     ) 
 
    } 
 
} 
 

 
export default PlayerWrapper;

webpack xây dựng tập tin

var webpack = require('webpack'); 
 

 
module.exports = { 
 
    devtool: 'inline-source-map', 
 
    entry: [ 
 
     'webpack-hot-middleware/client', 
 
     './app/PlayerWrapper.js' 
 
    ], 
 
    output: { 
 
     path: require("path").resolve("./dist/app"), 
 
     filename: 'index.js', 
 
     publicPath: '/' 
 
    }, 
 
    plugins: [ 
 
     new webpack.optimize.OccurrenceOrderPlugin(), 
 
     new webpack.HotModuleReplacementPlugin(), 
 
     new webpack.NoErrorsPlugin() 
 
    ], 
 
    module: { 
 
     loaders: [{ 
 
      test: /\.js?$/, 
 
      exclude: /node_modules/, 
 
      loader: 'babel-loader', 
 
      query: { 
 
       presets: ['react', 'es2015'] 
 
      } 
 
     }, 
 
     { test: /\.css$/, loader: ["css-loader","style-loader"] }, 
 
     { test: /\.scss$/, loader: "sass-loader" }, 
 
     { test: /\.(ttf|eot|svg|eot|woff|otf|png|gif)(\?v)*/, loader: "file-loader?name=fonts/[name].[ext]" } 
 
     ] 
 
    } 
 
};

+1

Vì vậy, vấn đề ở đây là gì? Bạn nên sử dụng các dấu ngoặc nhọn vì 'connect' và' bindActionCreators' được đặt tên là import. –

+0

tôi đăng những gì tôi đã làm suy nghĩ nó sẽ giải quyết vấn đề, nhưng sau đó tìm thấy những gì bạn đã đề cập. bây giờ tôi đang sử dụng dấu ngoặc nhọn, sau đó tôi nhận được lỗi đầu tiên. tự hỏi làm thế nào để giải quyết vấn đề, tại sao tôi nhận được các vấn đề trong thông báo lỗi đầu tiên? –

+0

vui lòng đăng mã cuối cùng. –

Trả lời

0

Các lỗi chỉ ra rằng trong lệnh gọi reactDOM.render (whi ch bạn không bao giờ hiển thị), bạn chỉ chuyển một hàm hoặc tên lớp thay vì một cá thể thành phần.

Ví dụ, ví dụ dưới đây là sai:

ReactDOM.render (myComponent, tài liệu.getElementById ('MyComponent'));

Và việc sửa chữa là để biến tham số đầu tiên vào một trường hợp thành phần của gói nó trong dấu ngoặc nhọn:

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

13

Tôi vừa dành chút thời gian gỡ lỗi thứ hai được mô tả ở đây và tìm hiểu một chút về cú pháp nhập ES6 trong quy trình.

Dòng:

import connect from 'react-redux';

sẽ nhập xuất khẩu mặc định từ phản ứng-Redux thư viện. Đây là nguồn gốc của lỗi:

Uncaught TypeError: (0 , _reactRedux2.default) is not a function

Thay đổi nó để:

import { connect } from 'react-redux';

sẽ nhập khẩu các đối tượng từ bên trong thư viện phản ứng-Redux tên kết nối mà trong trường hợp cụ thể là những gì bạn muốn . Lưu ý các dấu ngoặc nhọn

Kiểm tra các tài liệu MDN here

Tôi cũng đã có một lỗi tương tự để là người đầu tiên:

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).

khi tôi đã không được nhập thành phần định nghĩa của tôi một cách chính xác như trên .

+0

Giống như một sự quyến rũ. Cảm ơn. –

+0

'import {Class} ...' không bằng 'import class ...' - bravo! tôi không biết và sẽ không tìm ra được nếu không có ai đó nói với tôi! – pstanton

0

Các lỗi có nghĩa là ở đâu đó bạn đang cố gắng để làm cho một cái gì đó mà không phải là một thành phần thực tế (hoặc chuỗi)

Như đã nói bạn cần phải destructure kết nối và bindActionCreators vì họ không phải là xuất khẩu mặc định các gói tương ứng của họ . Đối với lỗi của bạn, nó cũng có thể là khi bạn đang cố gắng để render đạo cụ không có gì để render (ví dụ như null hoặc undefined) nhưng vì bạn chưa đăng mã mà bạn gọi là ReactDOM.render I không thể chắc chắn.

Các vấn đề liên quan