Jeroen Wienk
Jeroen Wienk

Reputation: 2030

React router invalid prop `component` supplied to `Route`

In my project react router seems to have issues to validate some of my components and I get this error in the console. Somehow it worked fine before but now I have changed something and it doesnt work anymore. Can anyone see the issue here? Is it something to do with the webpack config?

Warning: Failed propType: Invalid prop `component` supplied to `Route`.
Warning: [react-router] Invalid undefined `component` supplied to `Route`.

index.js

The appbar renders fine and I can also navigate to the MatchesPage and IndexPage which only contain a class based component with a single div. However when I navigate to other components nothing happens. At the bottom of this page I have a component example users-page.js that does not render.

import React from 'react';
import ReactDOM from 'react-dom';
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import Theme from './theme';
import injectTapEventPlugin from 'react-tap-event-plugin';
import AppBar from './components/app-bar/app-bar';
import IndexPage from './components/index-page/index-page';
import Matches from './components/matches-page/matches-page';
import Users from './components/users-page/users-page';
import Register from './components/register-page/register-page';
import Login from './components/login-page/login-page';
import Profile from './components/profile-page/profile-page';
import { Router, Route, IndexRoute, hashHistory } from 'react-router';
import Firebase from 'firebase';
import css from './main.scss';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.firebaseRef = new Firebase('myurl');
    this.firebaseRef.onAuth(this.authDataCallBack);
  }

  authDataCallBack = (authData) => {
    console.log('authDataCallBack');
    if (authData) {
      console.log('User ' + authData.uid + ' is logged in with ' + authData.provider);
      this.firebaseRef.child('users').child(authData.uid).update({
        provider: authData.provider,
        email: authData.password.email
      });
    } else {
      console.log('User is logged out');
    }
  }

  componentWillUnmount() {
    this.firebaseRef.offAuth(this.authDataCallBack);
  }

  static childContextTypes = {
    muiTheme: React.PropTypes.object
  }

  getChildContext() {
    return {
      muiTheme: ThemeManager.getMuiTheme(Theme)
    };
  }

  render() {
    return (
      <div>
        <AppBar className={css.appbar} />
        <div className={css.container} >
          {this.props.children}
        </div>
      </div>
    );
  }
}

injectTapEventPlugin();
ReactDOM.render((<Router history={hashHistory}>
  <Route path="/" component={App}>
    <IndexRoute component={IndexPage}/>
    <Route path="matches" component={Matches}/>
    <Route path="users" component={Users}/>
    <Route path="register" component={Register}/>
    <Route path="login" component={Login}/>
    <Route path="profile" component={Profile}/>
  </Route>
</Router>), document.getElementById('app'));

webpack.config.js

var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');



module.exports = {
  context: __dirname + "/src",
  devtool: "#inline-source-map",
  entry: ['webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8080', path.resolve(__dirname, 'src/index.js')],
  output: {
    path: path.resolve(__dirname),
    filename: 'bundle.js',
  },
  resolve: {
    extensions: ['', '.jsx', '.scss', '.js', '.css']
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: [ "babel-loader", "eslint-loader" ],
        exclude: /node_modules/
      },
      {
        test: /\.(css|scss)$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader')
      }]
    },
    plugins: [
      new ExtractTextPlugin("styles.css")
    ]
  };

package.json

{
  "name": "atc-react-webpack",
  "version": "1.0.0",
  "description": "Website ATC10",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server --devtool eval --progress --colors --hot"
  },
  "author": "Jeroen Wienk",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.5.1",
    "babel-eslint": "^5.0.0",
    "babel-loader": "^6.2.2",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "css-loader": "^0.23.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "node-sass": "^3.4.2",
    "sass-loader": "^3.1.2",
    "style-loader": "^0.13.0",
    "eslint": "^2.1.0",
    "eslint-loader": "^1.3.0",
    "eslint-plugin-react": "^3.16.1",
    "webpack": "^1.12.13",
    "webpack-dev-server": "^1.14.1"
  },
  "dependencies": {
    "babel-polyfill": "^6.5.0",
    "classnames": "^2.2.3",
    "firebase": "^2.4.1",
    "flexboxgrid": "^6.3.0",
    "material-ui": "^0.14.4",
    "normalize.css": "^3.0.3",
    "react": "^0.14.7",
    "react-dom": "^0.14.7",
    "react-flexbox-grid": "^0.9.4",
    "react-router": "^2.0.0",
    "react-tap-event-plugin": "^0.2.2"
  }
}

users-page.js

This is not a valid component somehow.

import React from 'react';
import UsersList from './users-list';
import Firebase from 'firebase';
import _ from 'lodash';
import css from './users-page.scss';

export default class UsersPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: []
    };
    this.firebaseRef = new Firebase('myurl');
  }

  componentWillUnmount() {
    this.firebaseRef.off();
  }

  componentWillMount() {
    this.firebaseRef.on('value', (snapshot) => {
      let usersVal = snapshot.val();
      let users = _(usersVal)
      .keys()
      .map((key) => {
        let cloned = _.clone(usersVal[key]);
        cloned.key = key;
        return cloned;
      }).value();
      this.setState({
        users: users
      });
    });
  }

  callback = () => {
    console.log(this.state.users);
  }

  render() {
    return (
      <div className={css.usersPageRoot}>
        <h3 className={css.usersPageHeading}>SPELERS</h3>
        <div className={css.usersPageContentContainer}>
          <UsersList users={this.state.users}/>
        </div>
      </div>
    );
  }
}

Upvotes: 2

Views: 2807

Answers (1)

Jeroen Wienk
Jeroen Wienk

Reputation: 2030

I found the solution, the names for the scss files were the same as the component name and this caused the router to try and render a scss file I guess.

Upvotes: 1

Related Questions