最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pass class object to ReactJS component - Stack Overflow

programmeradmin0浏览0评论

I get the following error:

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

I also get this warning from React:

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

The actual problem I have faced (as I understood through debugging) is that I can't pass class as an argument, like this: <BigCard pokemon={result} />, because result here is an object of the class. What should I do to make it work correctly. Are there any best practices out there for passing classes as arguments?

I have this ponent:

export var BigCard = React.createClass({
  render: function() {
    var rows = [];
    var pokemon = this.props.pokemon;
    for (var variable in pokemon) {
      if (pokemon.hasOwnProperty(variable) && variable.toString() !== 'id' && variable.toString !== 'name' && variable.toString !== 'image' && variable.toString !== 'types') {
        rows.push(
          <tr>
            <td class='mdl-data-table__cell--non-numeric'>
              {variable}
            </td>
            <td>
              {pokemon[variable]}
            </td>
          </tr>
        )
      }
    }
    return (
      <div class='mdl-card mdl-shadow--4dp'>
        <div class='mdl-card__title'>
          <img src={pokemon.image.src} alt='Pokemon' class='bigCard__img'/>
        </div>
        <h2 class='mdl-card__title-text'></h2>
        <div class='mdl-card__supporting-text'>
          <table class='mdl-data-table mdl-js-data-table'>
            <thead>
              <tr>
                <th class='mdl-data-table__cell--non-numeric'>Type</th>
                <th class='mdl-data-table__cell--non-numeric'>{pokemon.types}</th>
              </tr>
            </thead>
            <tbody>
              {rows}
            </tbody>
          </table>
        </div>
      </div>
    );
  }
});

I have the following code, that I would like to run:

import React from 'react';
import ReactDOM from 'react-dom';
import * as DataLogic from './modules/data-logic.js';
import SmallCard from './ponents/SmallCard.jsx';
import BigCard from './ponents/BigCard.jsx';

DataLogic.getPokemonById(3).then((result) => {
  ReactDOM.render(
    <BigCard pokemon={result} />,
    document.getElementById('bigCard')
  );
}).catch((error) => console.log(`${error} in main.js`));

The result of getPokemonById is object of class DetailedPokemon. This is my class, which serves as a viewmodel:

export default class DetailedPokemon {
  constructor(id, name, image, types, attack, defense, hp, spAttack, spDefense, speed, weight, totalMoves) {
    this.id = id;
    this.name = name;
    this.image = image;
    this.types = types;
    this.attack = attack;
    this.defense = defense;
    this.hp = hp;
    this.spAttack = spAttack;
    this.spDefense = spDefense;
    this.speed = speed;
    this.weight = weight;
    this.totalMoves = totalMoves;
  }
}

I hope, I explained everything clearly. Can you help me with my problem please?

I get the following error:

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

I also get this warning from React:

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

The actual problem I have faced (as I understood through debugging) is that I can't pass class as an argument, like this: <BigCard pokemon={result} />, because result here is an object of the class. What should I do to make it work correctly. Are there any best practices out there for passing classes as arguments?

I have this ponent:

export var BigCard = React.createClass({
  render: function() {
    var rows = [];
    var pokemon = this.props.pokemon;
    for (var variable in pokemon) {
      if (pokemon.hasOwnProperty(variable) && variable.toString() !== 'id' && variable.toString !== 'name' && variable.toString !== 'image' && variable.toString !== 'types') {
        rows.push(
          <tr>
            <td class='mdl-data-table__cell--non-numeric'>
              {variable}
            </td>
            <td>
              {pokemon[variable]}
            </td>
          </tr>
        )
      }
    }
    return (
      <div class='mdl-card mdl-shadow--4dp'>
        <div class='mdl-card__title'>
          <img src={pokemon.image.src} alt='Pokemon' class='bigCard__img'/>
        </div>
        <h2 class='mdl-card__title-text'></h2>
        <div class='mdl-card__supporting-text'>
          <table class='mdl-data-table mdl-js-data-table'>
            <thead>
              <tr>
                <th class='mdl-data-table__cell--non-numeric'>Type</th>
                <th class='mdl-data-table__cell--non-numeric'>{pokemon.types}</th>
              </tr>
            </thead>
            <tbody>
              {rows}
            </tbody>
          </table>
        </div>
      </div>
    );
  }
});

I have the following code, that I would like to run:

import React from 'react';
import ReactDOM from 'react-dom';
import * as DataLogic from './modules/data-logic.js';
import SmallCard from './ponents/SmallCard.jsx';
import BigCard from './ponents/BigCard.jsx';

DataLogic.getPokemonById(3).then((result) => {
  ReactDOM.render(
    <BigCard pokemon={result} />,
    document.getElementById('bigCard')
  );
}).catch((error) => console.log(`${error} in main.js`));

The result of getPokemonById is object of class DetailedPokemon. This is my class, which serves as a viewmodel:

export default class DetailedPokemon {
  constructor(id, name, image, types, attack, defense, hp, spAttack, spDefense, speed, weight, totalMoves) {
    this.id = id;
    this.name = name;
    this.image = image;
    this.types = types;
    this.attack = attack;
    this.defense = defense;
    this.hp = hp;
    this.spAttack = spAttack;
    this.spDefense = spDefense;
    this.speed = speed;
    this.weight = weight;
    this.totalMoves = totalMoves;
  }
}

I hope, I explained everything clearly. Can you help me with my problem please?

Share Improve this question edited Mar 28, 2016 at 22:11 Evan Davis 36.7k7 gold badges52 silver badges58 bronze badges asked Mar 28, 2016 at 21:37 Andrew SklyarAndrew Sklyar 2935 silver badges16 bronze badges 2
  • What's the error you are getting? JSON.parse is for parsing strings containing JSON. If result is an object then you should not pass it to JSON.parse. – Felix Kling Commented Mar 28, 2016 at 21:39
  • @FelixKling thank you, I have edited the question! – Andrew Sklyar Commented Mar 28, 2016 at 21:55
Add a ment  | 

2 Answers 2

Reset to default 3

You import BigCard incorrectly, perhaps SmallCard too.

When you export something with export foo = 'bar', foo is imported using curly brackets: import {foo} from './fooFile'.

If you want to import using import foo from ./fooFile, fooFile has to export a default: export default const BigCard = React.createClass(...

and that should take care of it.

This is likely from importing something the wrong way. I think this will work:

In your main app file:

import BigCard from './ponents/BigCard';

At the top, just assign a regular variable:

var BigCard = React.createClass({...})

And at the bottom of your BigCard ponent:

export default BigCard;

There are a few ways to do this, with ES6:


By extending React.Component:

export default class BigCard extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (<div>MyComponent</div>);
  }
}

Note the use of React.Component instead of React.createClass, they are almost the same. However with React.Component, ponentWillMount logic is placed in the constructor. Along with a few other notable differences: https://toddmotto./react-create-class-versus-ponent/


With React.createClass:

const BigCard = React.createClass({
  render() {
    return (
      <div></div>
    );
  }
});

export default BigCard;
发布评论

评论列表(0)

  1. 暂无评论