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. Ifresult
is an object then you should not pass it toJSON.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
2 Answers
Reset to default 3You 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;