When I run my code on browser, I'm getting this error message.
Uncaught Invariant Violation: MyComponent.render(): A valid React
element (or null) must be returned. You may have returned undefined,
an array or some other invalid object.
I'm using Atom as my code editor and running on a chrome web server. Here is my code.
<body>
<div id="react-comp"></div>
<script type="text/babel">
var MyComponent = React.createClass({
render: function() {
return
<div>
<h1>{this.props.text}</h1>
</div>;
}
});
ReactDOM.render(
<div>
<MyComponent text="Hello World"/>
<MyComponent text="Hello"/>
</div>
, document.getElementById('react-comp'));
</script>
</body>
It might be a jsx transforming issue? or any other thing?
You are likely hitting JavaScripts automatic semicolon insertion after return. Just remove the line break before your div.
var MyComponent = React.createClass({
render: function() {
return <div> // Change this line
<h1>{this.props.text}</h1>
</div>;
}
});
I don't know which version of React you are using, as I know some old version makes error if the JSX syntax isn't wrapped with ().
Try to do this on MyComponent's render method:
render: function() {
return (
<div>
<h1>{this.props.text}</h1>
</div>
);
}
Just change your render function to
var MyComponent = React.createClass({
render: function() {
return (
<div>
<h1>{this.props.text}</h1>
</div>
);
}
});
Daniel's suggestion is also correct.
Related
I create a very generic Modal that can get different header, body and footer, but also different arguments for their Reactstrap components (I'm using Reactstrap to create the Modal but the question needn't be specific to solve a Reactstrap problem).
My GenericModal.js code looks like:
class GenericModal extends React.Component{
render(){
return(
<Reactstrap.Modal {...this.props.other} />
<Reactstrap.ModalHeader {...this.props.headerArgs}>{this.props.header}</Reactstrap.ModalHeader>
<Reactstrap.ModalBody {...this.props.bodyArgs}>{this.props.body}</Reactstrap.ModalBody>
<Reactstrap.ModalFooter {...this.props.footerArgs}>{this.props.footer}</Reactstrap.ModalFooter>
</Reactstrap.Modal>);
}
}
And so I call this class like this:
<GenericCard {...{other: other, headerArgs: headerArgs, bodyArgs: bodyArgs, footerArgs: footerArgs,
cardheader:header, cardbody:body, cardfooter:footer}} />
Now I know that this method works because I've tried it with className, for example:
const bodyArgs = {className: 'my-5'};
I want to also be able to pass an onClick function - but not merely the function (as we can see in this question), but the whole thing: onClick=foo().
I'm having a bit of a problem understanding how I can put the onClick method inside a json-style format like I did with className.
I can't write an anonymous function for the onClick inside const bodyArgs = {...}, and writing it as
const bodyArgs = {onClick: {foo}};
Provides an undefined foo. I also can't put this.foo because it's an unexpected syntax as well.
Any thoughts?
Welp, found the solution moments after I posted this.
Just didn't need the {} curly brackets.
const bodyArgs = {onClick: this.foo};
Does the job.
Thought I'd keep it here in case anyone stumbles into this issue.
This should work as you have explained but I cannot fully know without the whole example. Here is a working bit of code and a codesandbox link of what you are tying to do.
import React from "react";
import "./styles.css";
class ClickExecutor extends React.Component {
render() {
return (
<div>
<h4>Click Executor</h4>
<div>
<button onClick={() => this.props.bodyArgs.alert1()}>One</button>
<button onClick={() => this.props.bodyArgs.alert2()}>Two</button>
</div>
</div>
);
}
}
class GenericModal extends React.Component {
alert1 = () => {
alert("Alert 1");
};
alert2 = () => {
alert("Alert 2");
};
render() {
const bodyArgs = {
alert1: this.alert1,
alert2: this.alert2
};
return (
<div>
<h1>Generic Modal</h1>
<ClickExecutor
{...{
bodyArgs: bodyArgs,
otherProps: "other various properties ..."
}}
/>
</div>
);
}
}
export default function App() {
return (
<div className="App">
<GenericModal />
</div>
);
}
Working Demo LINK : https://codesandbox.io/s/smoosh-frost-rj1vb
I'm new in React but I'm building a simple app to search GitHub users just put their usernames. It must bring me information about the users and theirs respective repositories, but I have a problem whit the code:
Errors:
Uncaught (in promise) TypeError: this.props.repos.map is not a function
Uncaught (in promise) TypeError: Cannot read property '_currentElement' of null
Code:
var React = require('react');
var UserRepos = React.createClass({
getInitialState: function () {
return {
reposCount: 0,
}
},
componentWillReceiveProps: function (props) {
console.log(props);
this.setState({reposCount: props.repos.length});
},
render: function () {
var repos = this.props.repos.map(function (repo, key) {
return (
<div key={key} className="thumbnail">
<div className="caption">
<h3>{repo.name}
<span className="badge">{repo.stargazers_count} STARS</span>
</h3>
<p>{repo.description}</p>
<p>
Repository
Issues ({repo.open_issues})
</p>
</div>
</div>
);
});
return (
<div>
<h2>{this.state.reposCount} repositories</h2>
{repos}
</div>
)
}
});
module.exports =UserRepos;
Problem Solved!
Hi guys thanks for your help!
This was a beginner error!!!
In js file called UserInfo.js where I have a props was:
<UserRepos repos="{props.repos}" />
I just corrected it for
<UserRepos repos={props.repos} />
without quotes!
Thanks a million!!!
You can fix error by doing this:
render: function () {
var reposArray=this.props.repos || [];
var repos = reposArray.map(function (repo, key) {
...
...
....
What this will do is that if this.props.repos is not array (probably undefined) it will initialize reposArray variable to empty array.
This error means that this.props.repos is not an array.
So first of all ensure that repos passed to component is an array:
<UserRepos repos={[repo1, repo2, ...]} />
Also I'd like to recomend you to declare your component's propTypes:
import React from 'react';
import PropTypes from 'prop-types';
export default React.createClass({
propTypes: {
repos: PropTypes.array,
},
getDefaultProps() {
return {
repos: [],
};
},
...
});
Note: you need to install prop-types for this: npm install --save prop-types
I would agree with the others on your issue most probably being one of the following:
You haven't passed the repos prop properly. Check the parent method
for this one.
repos is not always an array. See how you are initialising it before you assign data to this variable. You can set it initially as
let repos = []; to have it as an empty array before it gets any
data.
Also, if you are new to React, definitively go with PropTypes, they are a life saver, and will help you catch these kinds of issues on component mounting.
This is my take on your issue (ES6): https://jsfiddle.net/Lx9gfj5f/3/
I am using React 15.1.0.
Suppose there is Parent "P" Component, and it contains a child component "C".
In older versions of react, when I wanted to pass the entire state to child, we used {...this.state} and then we used {this.props.something} from child component.
Is there a simple way in latest Latest React 15.1.0 for above Instance?
Note: I need to pass entire state and not individual props.
<div>
{React.cloneElement(this.props.children, { title: this.state.title })}
</div>
What I am expecting is something like below;
<div>
{React.cloneElement(this.props.children, {...this.state})}
</div>
In Parent component I have below code;
var App = React.createClass({
getInitialState() {
return{
status: 'disconnected',
title: 'Hello World'
}
},
render() {
return(
<div>
<Header title={this.state.title} />
<div>
{React.cloneElement(this.props.children, this.state)}
</div>
</div>
);
}
});
In Child Component I am experimenting using below code.
var Speaker = React.createClass({
render() {
return (
<h1>Speaker: {this.state.title}</h1>
);
}
});
But in Chrome Browser, I get below result;
{...this.state}
equals
this.state
in this case.
Spread operator in ES6 (not React-specific feature) ... expands one objects' properties into the parent object, see:
let sampleObject = {
name: 'a_name'
};
console.log('Non-spread', sampleObject); // Non-spread {name: "a_name"}
console.log('Spread', {... sampleObject}); // Spread {name: "a_name"}
I just changed the below code snippet,
Speaker: {this.props.title}
in child component and voila!!! the code worked. Thank you all guys.
Below is the snapshot.
I'm using django-pipeline along with browserify based on the documentation here -
http://gregblogs.com/how-django-reactjs-and-browserify/
I have it working perfectly fine when loading NPM/Bower packages like so -
'build_js': {
'source_filenames': (
'js/bower_components/jquery/dist/jquery.js',
'bootstrap/js/bootstrap.js',
'js/bower_components/react/react-with-addons.js',
'js/bower_components/react/react-dom.js',
'datatables/js/jquery.dataTables.js',
'datatables/js/dataTables.bootstrap.js',
'js/node_modules/marked/marked.min.js',
'js/node_modules/react-router/umd/ReactRouter.js',
'js/child.js',
'js/parent.js',
'js/build.browserify.js',
),
'output_filename': 'js/build_js.js',
The problem is I'm trying to reference the child.js and parent.js within the build.browserify.js
This is the contents of the 3 files -
child.js
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
parent.js
var Parent = React.createClass({
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
build.browserify.js
ReactDOM.render(
<Parent />,
document.getElementById('content')
);
I actually get 3 errors in my browser -
The following happens on my child.js and parent.js files both on line 4 -
Uncaught SyntaxError: Unexpected token <
And then I get this on my build.browserify.browserified.js at line 3
Uncaught ReferenceError: Parent is not defined
This is the contents of that file -
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
ReactDOM.render(
React.createElement(Parent, null),
document.getElementById('content')
);
},{}]},{},[1]);
edit -
If I put all code in a single build.browserify.js file like this it works -
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
var Parent = React.createClass({
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
#taylorc93 is on the right track with this, but you're missing an additional step.
In addition to having to do require('./parent') in any file where you want to include the parent module, you also need to actually export the content of the parent.js file. So, parent.js should look like:
child.js
var React = require('react');
modules.export = React.createClass({
displayName: 'Child', // Always setting React component's displayName will make your error messages easier to understand
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
parent.js
var React = require('react');
var Child = require('./child');
modules.export = React.createClass({
displayName: 'Parent', // Always setting React component's displayName will make your error messages easier to understand
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
build.browserify.js
var ReactDOM = require('react-dom');
var Parent = require('./parent');
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
Also, while not required, it's good practice to give Component files uppercase names, just like you would class files in Java. Most apps will also name the root file as app.js or main.js or something like that, rather than build.browserify.js which is a bit vague since technically the file has nothing to do with building or with Browserify.
The react class myComponent is not rendering inside the element example1.
what I am able to get in console is
You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx
code
<script type="text/jsx">
var myComponent = React.createClass({
render: function() {
return (
<h2>{this.props.name} wants to eat {this.props.food}</h2>
);
}
});
React.render(
<div>
<myComponent food="fruits" name="Raj1"/>
<myComponent food="Veggies" name="Raj2"/>
<myComponent food="Chicken" name="Raj3"/>
<myComponent food="Burger" name="Raj4"/>
</div>,
document.getElementById('example1'));
</script>
You must capitalize your react classes
var MyComponent = React.createClass({
render: function() {
return (
<h2>{this.props.name} wants to eat {this.props.food}</h2>
);
}
});
working fiddle example