2016-05-05 24 views
8

Ho eseguito un componente con un negozio che utilizza react, redux e react-redux. il bundle del codice è fatto con webpack. (Controllare i codici allegati sotto)Errore nell'utilizzo del componente eseguito con react, redux e react-redux e creazione con Webpack in un'applicazione reattiva

quando volevo usare il componente di costruzione del webpack all'interno di un altro progetto di reazione ho affrontato i seguenti problemi.

  • 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.

poi sono andato avanti e fare la seguente modifica nel codice, in precedenza ho avuto un incarico di destrutturazione come qui di seguito per collegare e bindActionCreators

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

Poi ho cambiato come qui di seguito, rimuovendo le parentesi graffe intorno connettersi e 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 {

Ma dopo che sto affrontando l'errore sotto, come credo che questo ha qualcosa a che fare con Babel che esegue il transponder da ES6 a ES5, ma non è sicuro di quali passi seguire per risolvere questo problema, vorrebbe ottenere una risposta o alcuni suggerimenti per risolvere il problema?

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

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

codice componente

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)

codice wrapper componente

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;

file di webpack accumulo

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

Quindi qual è il problema qui? Dovresti utilizzare le parentesi graffe poiché 'connect' e' bindActionCreators' sono denominati importazioni. –

+0

ho postato quello che ho fatto pensando che risolverà il problema, ma in seguito ho trovato quello che hai menzionato. ora sto usando le parentesi graffe, poi sto ricevendo il primo errore. chiedendo come risolvere il problema, perché sto ricevendo i problemi nel primo messaggio di errore? –

+0

per favore inserisci il codice finale. –

risposta

0

L'errore indica che nella chiamata a reactDOM.render (WHI ch non si mostra mai), hai passato solo una funzione o un nome di classe invece di un'istanza di componente.

Ad esempio, l'esempio che segue è sbagliato:

ReactDOM.render (MyComponent, documento.getElementById ('MyComponent'));

E la correzione è quello di trasformare il primo parametro in un'istanza di componente avvolgendolo in parentesi angolari:

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

13

Ho appena trascorso un po 'di tempo per il debug del secondo errore descritto qui e ho appreso un po' della sintassi di importazione ES6 nel processo.

La linea:

import connect from 'react-redux';

importerà il esportazione predefinito dal reagire-redux libreria . Questa è l'origine dell'errore:

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

Modifica a:

import { connect } from 'react-redux';

importerà l'oggetto all'interno della libreria reagire-redux nome collegare, che nel caso particolare è quello che volete . Nota le parentesi graffe

Scopri la documentazione MDN here

Ho anche avuto un errore simile al primo:

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).

quando non ho importato i miei componenti definiti correttamente come sopra .

+0

Come un incantesimo. Grazie. –

+0

'import {Class} ...' non è uguale a 'import Class ...' - bravo! non ne avevo idea e non l'avrei capito senza che qualcuno me lo dicesse! – pstanton

0

L'errore significa che da qualche parte si sta tentando di rendere qualcosa che non è un componente effettivo (o stringa)

Come detto in precedenza è necessario destrutturare collegare e bindActionCreators perché non sono l'esportazione di default dei rispettivi pacchetti .

Per quanto riguarda l'errore, è ugualmente possibile che quando si tenta di eseguire il rendering di oggetti di scena non ci sia nulla da rappresentare (ad es. È nullo o indefinito) ma dal momento che non si è registrato il codice in cui è stato chiamato ReactDOM.render I non posso essere sicuro.