ReactJS doesn't render in IE11 - javascript

My site works flawlessly in web browsers, but IE11 shows this error in console.
What should I do with this?
React.render(
<NewsFeed tagFilter={tagFilter}/>,
document.getElementById('newsFeed')
);
'NewsFeed' is undefined
EDIT:
Here is the newsfeed (.js JSX file, included in page's header)
var Article = React.createClass({
askDelete: function(id,title) {
if (confirm("Delete the '"+title+"'?")) {
$.ajax({
url: "/-----removed----/"+id,
type: "DELETE",
async: false,
cache: false,
dataType: 'json'
});
location.reload();
}
},
handleClick: function(id) {
React.unmountComponentAtNode(document.getElementById('editor'));
React.render(
<PostEditor
postId={id}
/>,
document.getElementById('editor')
);
functAdmin.showEditor();
},
render: function() {
var editIcon=[];
var boundClick = this.handleClick.bind(this, this.props.id);
var boundDeleteClick = this.askDelete.bind(this, this.props.id,this.props.title);
editIcon.push(<span className="adminActionsNewsfeed" key={"editIcon"+this.props.id}><i className="pointer gray fa fa-edit" onClick={boundClick}></i><i className="pointer fa fa-remove red" onClick={boundDeleteClick} key={"deleteNewsIcon"+this.props.id}></i></span>);
var tags=[];
if (typeof this.props.tags != 'undefined') {
var tagArray=this.props.tags.split(",");
for(tag of tagArray){
tags.push({tag});
}
}
return (
<div className="article" key={"newsArticle"+this.props.id}>
{editIcon}
<span className="articleTitle">
{this.props.title}
</span>
<span className="articleTime">
{funct.formatDate(this.props.time)}
</span>
<div className="articleBody">
{this.props.children}
</div>
<div className="tagLine">{tags}</div>
</div>
);
}
});
var ArticleList = React.createClass({
render: function() {
this.props.data.sort(funct.SortByTime);
var postNodes = this.props.data.map(function (item) {
var tags = item.news_tags.toLowerCase().split(",");
if ((tagFilter=="") || (tags.indexOf(tagFilter) > -1)) {
return (
<Article
key={"news"+item.news_id}
title={item.news_title}
tags={item.news_tags}
time={item.news_time}
id={item.news_id}
>
{item.news_body}
</Article>
);
}
});
return (
<span>
{postNodes}
</span>
);
}
});
var NewsFeed = React.createClass({
launchAdd: function() {
React.unmountComponentAtNode(document.getElementById('editor'));
React.render(
<PostEditor
postId={""}
/>,
document.getElementById('editor')
);
functAdmin.showEditor();
},
getInitialState: function() {
return {data: []};
},
refreshPostStatus: function() {
$.ajax({
url: "/-----removed----",
type: "GET",
cache: false,
dataType: 'json',
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.log( xhr.responseText);
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.refreshPostStatus();
},
render: function() {
var addIcon=[];
addIcon.push(<div className="addPostLine"><i className={funct.statusIcon[5]+" fa-2x"} onClick={this.launchAdd} />Add new post</div>);
return (
<span>
<i className="fa fa-file fa-lg blue"></i>
{addIcon}
<h1>Netbiter funct System Information</h1>
<ArticleList data={this.state.data}/>
</span>
);
}
});

Solved it.
IE11 didn't like this part of newsfeed.js:
for(tag of tagArray){
tags.push({tag});
}
It works after replacing it with this:
for(var i in tagArray){
var tag=tagArray[i];
tags.push({tag});
}

just import 'core-js/es6/' to your index.js or main entry file
import 'core-js/es6/';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app';
ReactDOM.render(<App />, document.getElementById('root'));

Related

Issue rendering ReactJS CRUD components in Rails app with Webpacker

I'm attempting to add CRUD functionality for a Rails resource through some ReactJS components. I am using webpacker.
At this stage, I get one error in the console:
Uncaught Error: Target container is not a DOM element.
My set up is:
React files are in app/javascript/Botanicals. I then have a app/javascript/packs where webpacker is compiling from into app/public/packs/manifest.json
My pack file is rendering the components:
app/javascript/packs/botanicalsCRUD.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import Botanicals from 'Botanicals'
document.addEventListener('turbolinks:load', function() {
var element = document.getElementById("botanicals");
ReactDOM.render(<Botanicals />, element);
});
I then individual files:
app/javascript/Botanicals/index.jsx
var Botanicals = React.createClass({
render() {
return (
<div>
<Body />
</div>
);
}
});
export default Botanicals
app/javascript/Botanicals/body.js.jsx
var Body = React.createClass({
getInitialState(){
return { botanicals: [] };
},
componentDidMount(){
$.getJSON('/botanicals.json', (response) => {
this.setState({ botanicals: response });
});
},
handleSubmit(item) {
var newState = this.state.botanicals.concat(botanical);
this.setState({ botanicals: newState })
},
handleDelete(id) {
$.ajax({
url: `/botanicals/%{id}`,
type: 'DELETE',
success: () => {
this.removeItemClient(id);
}
});
},
removeItemClient(id) {
var newBotanicals = this.state.botanicals.filter((botanical) => {
return botanical.id != id;
});
this.setState({ botanicals: newBotanicals });
},
render() {
return (
<div>
<NewItem handleSubmit={this.handleSubmit} />
<AllItems botanicals={this.state.botanicals} />
</div>
);
}
});
export default Body
app/javascript/Botanicals/newitem.js.jsx
var NewItem = React.createClass({
handleClick() {
var name = this.refs.name.value;
var description = this.refs.description.value;
$.ajax({
url: "/botanicals",
type: "POST",
data: { botanical: { name: name, description: description } },
success: botanical => {
this.props.handleSubmit(botanical);
}
});
},
render() {
return (
<div>
<input ref='name' placeholder='Enter the name of the item' />
<input ref='description' placeholder='Enter a description' />
<button onClick={this.handleClick}>Submit</button>
</div>
);
}
});
export default NewItem
app/javascript/Botanicals/allitems.js.jsx
var AllItems = React.createClass ({
handleDelete(id) {
this.props.handleDelete(id);
},
render() {
var botanicals = this.props.botanicals.map((botanical) => {
return (
<div key={botanical.id}>
<h3>{botanical.name}</h3>
<p>{botanical.description}</p>
<button onClick={this.handleDelete.bind(this, botanical.id)}>Delete</button>
</div>
);
});
return <div>{botanicals}</div>;
}
});
export default AllItems
views/botanicals/index.html.erb
<% javascript_pack_tag 'botanicalsCRUD' %>
<h1>Botanicals</h1>
<div id="botanicals"></div>
BotanicalsCRUD is in the manifest.json file:
"botanicalsCRUD.js": "/packs/botanicalsCRUD-b8ea47dea15aa535c997.js",
"botanicalsCRUD.js.map": "/packs/botanicalsCRUD-b8ea47dea15aa535c997.js.map",
My main suspicion is that render file in Packs isn't correctly finding botanicals/index.jsx.
I'm struggeling with the fact there isn't more error messages.
you should put <% javascript_pack_tag %> inside a div with the same id as you wrote in getElementById of your first react file.
that's mean in views/botanicals/index.html.erb you should write
<div id="botanicals">
<% javascript_pack_tag 'botanicalsCRUD' %>
</div>
hope it will work for you

How fetch json data in React

I am new in react and I'm learning on official website with tutorial help.
So, I have structure in my app:
-js
-notes.js
-comment.json
index.html
notes.js have next code:
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function () {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function(){
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
var CommentList = React.createClass({
render: function(){
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
render: function () {
return (
<div className="commentForm">
Hello, world! I am a CommentForm.
</div>
);
}
});
var Comment = React.createClass({
render: function () {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<p>
{this.props.children}
</p>
</div>
);
}
});
ReactDOM.render(
<CommentBox url="comment.json" pollInterval={2000} />,
document.getElementById('content')
);
Here my file data "comment.json":
[
{"id": "1", "author": "Pete Hunt", "text": "This is one comment"},
{"id": "2", "author": "Jordan Walke", "text": "This is *another* comment"}
]
But it doesn't work and in console I have next message:
jquery.js:9392 GET http://helper.com/views/com.json?_=1471986105038 404 (Not Found)
and another one:
notes.js:22 com.json error Not Found
Maybe I write wrong url parametr in:
<CommentBox url="comment.json" pollInterval={2000} />
Can anybody help me?

React multipages, component data passing

I'm doing a react app and id I'd like to know how to think multipages websites. Actually i'im I'm doing a course searcher,i searcher; I use routie to render the different components that renders render the page. The problem is that they arent aren't related by hierarchy, so the ajax data isn't accessible to the component that renders the result.I've I've tried vainly to use a js var data but doesnt var data but that doesn't work too either.Ive read https://facebook.github.io/react/tips/communicate-between-components.html
but i don't see what to do with own event system. If someone could illustrate the last paragraph of this doc it is great for all the people that are in this case.
var data = {};
var CourseSearcher = React.createClass({
getInitialState: function(){
return {
return { places: '',
branch: 0,
dayOfMonth: '',
timeStart: '',
timeEnd: '',
data: []};
},;
},
handlePlacesChange: function(e){
this.setState({places: e.target.value});
},
handleBranchChange: function(e){
this.setState({branch: e.target.value});
},
handleDayOfMonthChange: function(e){
this.setState({dayOfMonth: e.target.value});
},
handleTimeStartChange: function(e){
this.setState({timeStart: e.target.value});
},
handleTimeEndChange: function(e){
this.setState({timeEnd: e.target.value});
},
handleSubmit: function(e){
// stop the default browser action
e.preventDefault();
// Do an ajax post
$.ajax({
url:'php/results.php',
dataType: 'json',
type: 'GET',
data: {
data: {places: this.state.places,
branch:this.state.branch,
dayOfMonth:this.state.dayOfMonth,
timeStart:this.state.timeStart,
timeEnd:this.state.timeEnd},
},
success: function(data){
this.setState({data: data});
data = this.state.data;
routie('results');
}.bind(this),
error: function (xhr,status,err){
console.error('php/results.php',status,err.toString());
}.bind(this)
});
},
render: function(){
return(
<div>
<form method="get" onSubmit={this.handleSubmit}>
<label>Où?</label>
<input
type="text"
placeholder="Lieux"
value={this.state.places}
onChange={this.handlePlacesChange}
/>
<label>Quoi?</label>
<select value={this.state.branch} onChange={this.handleBranchChange}>
<option>Matière</option>
<option>Français</option>
<option>Anglais</option>
</select>
<label>Quand ?</label>
<input
type="date"
value={this.state.dayOfMonth}
onChange={this.handleDayOfMonthChange}
/>
<input
type="time"
value={this.state.timeStart}
onChange={this.handleTimeStartChange}
/> -
<input
type="time"
value={this.state.timeEnd}
onChange={this.handleTimeEndChange}/>
<button type="submit">Go!</button>
</form>
</div>
);
}
});
console.log(data);
var ResultList = React.createClass({
render: function() {
console.log(data);
return(
<h1>Hello</h1>);
}
);
}
});
var ResultBox = React.createClass({
render: function() {
return (
<div>
<h4>{}</h4>
</div>
);
}
});
routie({
'':function() {
React.render(<CourseSearcher />,
document.getElementById('content'));
},
'results': function() {
React.render(
React.render(<ResultList results={data} />,
document.getElementById('content'));
}
});
Done well with react router ;)
I've done it with react router where components are related to some dedicated urls

react load new content based on click

I have three separate files.
Nav.js
var NavItem = React.createClass({
render: function() {
return (
<li>{this.props.name}</li>
);
}
});
var NavList = React.createClass({
render: function() {
var navNodes = this.props.data.map(function(nav) {
return (
<NavItem name={nav.name} key={nav.id}></NavItem>
);
});
return (
<ul className="nav">
<li className="current"><i className="glyphicon glyphicon-home"></i> Lists</li>
{navNodes}
<li><i className="glyphicon glyphicon-plus"></i> Add New Widget List</li>
</ul>
);
}
});
var NavBox= React.createClass({
loadNavsFromServer: function() {
$.ajax({
url: "http://server/api/widgetlists/?format=json",
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error("http://server/api/widgetlists/?format=json", status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadNavsFromServer();
},
render: function() {
return (
<div className="col-md-2">
<div className="sidebar content-box" style={{display: "block"}}>
<NavList data={this.state.data} />
</div>
</div>
);
}
});
module.exports = {
NavBox: NavBox
}
Content.js
var Widgets = React.createClass({
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
$.ajax({
url: 'http://server/api/widgets/?list="xxxx"&format=json',
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error('http://server/api/widgets/?list="xxxx"&format=json', status, err.toString());
}.bind(this)
});
},
render: function() {
return (
<div className="col-md-10">
<div className="row">
<div className="col-md-6">
<div className="content-box-large">
<div className="panel-body">
<BootstrapTable data={this.state.data} striped={true}>
<TableHeaderColumn isKey={true} hidden={true} dataField="id">Widget ID</TableHeaderColumn>
<TableHeaderColumn dataField="title">Title</TableHeaderColumn>
<TableHeaderColumn dataField="username">Username</TableHeaderColumn>
<TableHeaderColumn dataField="price">Price</TableHeaderColumn>
</BootstrapTable>
</div>
</div>
</div>
</div>
</div>
);
}
});
module.exports = {
Widgets: Widgets
}
App.js
var Navigation = require("./components/Navigation/Navigation");
var Content = require("./components/Content/Content");
ReactDOM.render(
<Navigation.NavBox/>,
document.getElementById('navigation')
);
ReactDOM.render(
<Content.Widgets/>,
document.getElementById('content')
);
Depending on what link is clicked in Nav.js I want it to update the data in Content.js. NavItem in Nav.js would pass the list name into Content.js (the "xxxx" so that the table would load with the specific data based on that Item.
As #FakeRainBrigand mentions in his comment, this is a pretty typical use case for some type of event-based pattern like Flux.
https://facebook.github.io/flux/docs/overview.html
Basically, you want to create some type of singleton data store that keeps track of the list name. Attach a click handler to the NavItem component that causes a change to the list name in the store. The store should emit a change event in response to any changes. The Widgets component should listen for changes on the store, and when the Widgets component hears a change on the store, it should make another AJAX request with the new list item.
Let me know if you have any specific questions about implementation.

reactjs and rendering plain HTML

First of all I'm totally new to react so I'm not sure if my code is already written the "react way".
So far I've created a couple of react classes which render a Bootstrap Modal. To set the initial states I call an Ajax function within the componentsDidMount function. This works fine until I try to insert plain HTML into the modal body.
The server request works fine and I get plain HTML code in my this.state.data.content but if I try to insert this into the modal body I receive following error:
Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {__html}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons.
Does anyone know how to fix this? Am I even doing the right thing here?
Thanks!
<script type="text/babel">
var Modal = ReactBootstrap.Modal;
var Button = ReactBootstrap.Button;
var ButtonToolbar = ReactBootstrap.ButtonToolbar;
var L5fmHeaderButton = React.createClass({
render: function() {
var iconClass = "glyphicon " + this.props.buttonIcon;
return(
<button onClick={this.props.onClick} className="lfm-Modal-Button">
<span className={iconClass} aria-hidden="true"></span>
{this.props.buttonText}
</button>
);
}
});
var L5fmModalBody = React.createClass({
rawMarkup: function() {
return { __html: this.props.content };
},
render: function() {
return(
<Modal.Body>
dangerouslySetInnerHTML={this.rawMarkup()}
</Modal.Body>
);
}
});
var L5fmModal = React.createClass({
getInitialState : function() {
return {
data : []
};
},
componentDidMount: function() {
$.ajax({
url: 'L5fm/setInitialState',
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
console.log(data);
console.log(this.state.data);
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
changeDirectory : function() {
if (this.state.privateDir) {
this.setState({privateDir: false});
}
else {
this.setState({privateDir: true});
}
},
render: function() {
if(this.state.data.privateDir) {
var browseIcon = "glyphicon-folder-open";
var browseText = "browse all files";
}
else {
var browseIcon = "glyphicon-briefcase";
var browseText = "browse private files";
}
return(
<Modal {...this.props} bsSize="large" aria-labelledby="contained-modal-title-lg">
<Modal.Header closeButton>
<div className="header-button-group">
<L5fmHeaderButton buttonIcon="glyphicon-cloud-upload" buttonText="upload" />
<L5fmHeaderButton buttonIcon="glyphicon-list" buttonText="list View" />
<L5fmHeaderButton onClick={this.changeDirectory} buttonIcon={browseIcon} buttonText={browseText} />
</div>
</Modal.Header>
<L5fmModalBody content={this.state.data.content}/>
</Modal>
);
}
});
var App = React.createClass({
getInitialState: function() {
return { lgShow: false };
},
render: function() {
let lgClose = () => this.setState({ lgShow: false });
return (
<ButtonToolbar>
<Button bsStyle="primary" onClick={()=>this.setState({ lgShow: true })}>
Launch large demo modal
</Button>
<L5fmModal show={this.state.lgShow} onHide={lgClose} />
</ButtonToolbar>
);
}
});
ReactDOM.render(<App />, document.getElementById("modal"));
</script>
Well, as it seems, you are missing a div-tag where you wish to render your raw html
considering changing the Modal.Body code like this
var L5fmModalBody = React.createClass({
rawMarkup: function() {
return { __html: this.props.content };
},
render: function() {
return(
<Modal.Body>
<div dangerouslySetInnerHTML={createMarkup()} />
</Modal.Body>
);
}
});
otherwise the rendering gets broken because your markup cannot really be set as a child on the Modal.Body element

Categories