Rangana Sampath
Rangana Sampath

Reputation: 1467

Error using component done with react,redux and react-redux and build with webpack in react application

I have done a component with a store using react, redux and react-redux. bundling of the code is done with webpack.(please check the codes attached below)

when i wanted to use the webpack build component inside another react project i faced the following issues.

Then i went on and do the following modification in the code, earlier i had a destructuring assignment like below for connect and bindActionCreators

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

Then i changed it like below, by removing the curly braces around connect and 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 {

But after that i'm facing the below error, as i guess this is something to do with babel transpiling ES6 to ES5 , but not sure what steps to follow to resolve this, would like to get an answer or some pointers to get this resolved?

component code

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)

component wrapper code

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 build file

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]" }
        ]
    }
};

Upvotes: 14

Views: 7142

Answers (3)

Joshua Underwood
Joshua Underwood

Reputation: 927

The error means that somewhere you are attempting to render something which is not an actual component (or string)

As previously stated you need to destructure connect and bindActionCreators because they are not the default export of their respective packages.

As for your error, its equally possible that when you're attempting to render props there is nothing there to render (e.g. its null or undefined) but since you haven't posted the code where you called ReactDOM.render I can't be sure.

Upvotes: 0

lachlang
lachlang

Reputation: 241

I have just spent some time debugging the second error described here and learnt a bit about the ES6 import syntax in the process.

The line:

import connect from 'react-redux';

will import the default export from the react-redux library. This is the source of the error:

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

Changing it to:

import { connect } from 'react-redux';

will import the object from within the react-redux library named connect which in the particular case is what you want. Note the curly braces

Check out the MDN docs here

I have also had a similar error to the first:

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

when I haven't imported my defined components correctly as above.

Upvotes: 24

domehead100
domehead100

Reputation: 161

The error indicates that in your call to reactDOM.render (which you never show), you passed just a function or class name instead of a component instance.

For example, the example below is wrong:

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

And the fix is to turn the first parameter into a component instance by wrapping it in angle brackets:

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

Upvotes: 0

Related Questions