2016-05-05 30 views
8

Zrobiłem komponent ze sklepem za pomocą reagowania, redux i reagowania-redux. Wiązanie kodu odbywa się za pomocą pakietu internetowego (sprawdź kody dołączone poniżej)Błąd przy użyciu komponentu wykonanego z reakcją, redux i re- akcji-redux i budowania za pomocą pakietu sieciowego w aplikacji reakcji

kiedy chciałem użyć komponentu kompilatora sieci Web w innym projekcie reagowania, musiałem zmierzyć się z następującymi problemami.

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

Potem poszedłem dalej i zrobić następujące zmiany w kodzie, wcześniej miałem zadanie destructuring jak poniżej połączyć i bindActionCreators

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

potem zmienił go jak poniżej, usuwając nawiasy klamrowe wokół połączyć i 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 {

Ale po tym jestem stojące poniższy błąd, ponieważ myślę, że to ma coś wspólnego z babelem transponującym ES6 na ES5, ale nie mając pewności, jakie kroki należy podjąć, aby rozwiązać ten problem, chciałbyś uzyskać odpowiedź lub jakieś wskazówki, aby to rozwiązać?

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

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

kod składnik

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)

element kodu 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;

plik WebPack build

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

Więc jaki jest problem? Powinieneś używać nawiasów klamrowych, ponieważ 'connect' i' bindActionCreators' są nazwanymi importami. –

+0

napisałem, co zrobiłem, myśląc, że to rozwiąże problem, ale później znalazłem to, o czym wspomniałeś. teraz używam nawiasów klamrowych, a następnie otrzymuję pierwszy błąd. zastanawiasz się, jak rozwiązać problem, dlaczego pojawia się problem z pierwszym komunikatem o błędzie? –

+0

proszę napisać końcowy kod. –

Odpowiedz

0

Błąd wskazuje, że w wywołaniu reactDOM.render (whi ch nigdy nie wyświetlasz), przekazałeś tylko nazwę funkcji lub klasy zamiast instancji składnika.

Na przykład, przykład poniżej jest źle:

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

i poprawek jest włączenie pierwszego parametru w przypadku składnika przez owijanie go w rogu:

ReactDOM.render (< MyComponent/> document.getElementById („MyComponent”));

13

Właśnie spędziłem trochę czasu na debugowaniu drugiego błędu opisanego tutaj i dowiedziałem się trochę o składni importu ES6 w procesie.

Linia:

import connect from 'react-redux';

będzie importować domyślny eksport z reagować-Redux bibliotece. Jest to źródło błędu:

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

Zmiana go:

import { connect } from 'react-redux';

zaimportuje obiekt od wewnątrz biblioteki reagować-Redux nazwie łączenia, które w konkretnym przypadku jest to, co chcesz . Uwaga nawiasy klamrowe

Sprawdź Docs MDN here

Mam również miał podobny błąd do pierwszego:

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

kiedy nie przywozili swoje określone składniki poprawnie jak wyżej .

+0

Jak urok. Dzięki. –

+0

'import {Klasa} ...' nie jest równy 'importowi Klasy ...' - Bravo! nie miałem pojęcia i nie wymyśliłbym tego bez kogoś, kto by mi powiedział! – pstanton

0

Błąd oznacza, że ​​gdzieś próbujesz uczynić coś, co nie jest rzeczywiste komponent (lub ciąg znaków)

Jak już wspomniano trzeba destructure połączyć i bindActionCreators ponieważ nie są domyślne eksport swoich pakietach .

Co do twojego błędu, jest równie prawdopodobne, że podczas próby renderowania rekwizytów nie ma nic do renderowania (np. Jego wartość null lub undefined), ale ponieważ nie opublikowałeś kodu, w którym wywołałeś ReactDOM.render I nie mogę być tego pewien.