How to mount react_component from ajax html in rails - ruby-on-rails

I use this in ruby on rails with react-rails.
In my app ,I want to use ajax to get a html response:
<%= react_component('Post') %>
Post Component:
var Component = React.createClass({
render:function(){
return <div>Article</div>;
}
})
and attach it to App Component:
var App = React.createClass({
getInitialState:function(){
return {html:''};
},
componentDidMount:function(){
var that = this;
$.get('/home/component').done(function(data){
that.setState({html:data});
});
},
getHtml:function(){
return { __html:this.state.html};
},
render: function() {
return <div dangerouslySetInnerHTML={this.getHtml()}></div>;
}
});
But after that it is fail, which show:
<div data-react-class="Post" data-react-props="{}"></div>
I already add post.js app.js to index.html.
How can I mount this to DOM.
Thank.....

Related

Creating element in React for Rails

I am trying to create a button with a click event in React js. I cannot use JSX since it is not available in Rails. While creating element, it is firing error "Invalid component element."
var csearch_btn = React.createClass({
handleClick: function(index) {
console.log('content_input clicked');
}
,
render: function() {
return '<button class="btn btn-pill bg-color-blue-4" onClick=
{this.handleClick()}>Search</button>';
}
});
ReactDOM.render(csearch_btn ,
document.getElementById('content_Search_Btn'));

React / Rails : Append dynamically element to DOM

Currently following facebook tutorial on React (react_tuto).
I don't understand how 2 components can communicate so that on "submit a comment button" it appends dynamically the "comment list".
currently, comment are created on server but appears on page only when page refreshed
how can the comment appear on submit button?
This i my AddComment component
var AddComment = React.createClass({
getInitialState: function(){
return {
content: this.props.content,
adrien: "before"
}
},
handleKeyUp: function(e) {
this.setState({
content: this.refs.addComment.getDOMNode().value,
})
},
handleValidation: function() {
var that = this
$.ajax({
type: "POST",
data: {comment: { content: that.state.content } },
url: Routes.create_comment_path({format: 'json'}),
success: function(data) {
that.setState({
content: "",
adrien: "after"
})
}
})
},
render: function(){
return (
<div>
<textarea onKeyUp={this.handleKeyUp} value={this.state.value} ref="addComment"></textarea>
<button onClick={this.handleValidation}>submit</button>
</div>
)
}
})
This is my CommentList component:
var CommentList = React.createClass({
render: function() {
return (
<div>
{this.props.comments.map(function(comment){
return <CommentListElement key={comment.id} comment={comment} />;
})}
</div>
);
}
});
You need a common parent component for communication between different components.
I have updated you example a bit to include common parent component CommentSystem
Note: I have removed ajax call to just show the communication between component.
Check below link.
https://jsfiddle.net/j4yk3pzc/15/
Extra Info:
In react we store states on parent component and pass them down to children. Along with state we also pass actions to manipulate data down to the children. When child component want's to update data passed to it from parent, then it fires the action passed from the parent. This is called Data down action up approach. Data is passed from parent to child to grandchild. While actions are propagated from grandchild to child to parent.
If you don't want to create the parent component then you can use some Publish / Subscribe or EventEmitter based system to communicate between children having no common parent.
Reference:
http://ctheu.com/2015/02/12/how-to-communicate-between-react-components/
Code:
var CommentSystem = React.createClass({
getInitialState: function() {
return {
comments: []
}
},
addComments: function(comment) {
var comments = this.state.comments;
comments.push(comment);
this.setState({comments: comments})
},
render: function() {
return (
<div>
<AddComment addComments={this.addComments}/>
<CommentList comments={this.state.comments}/>
</div>
)
}
})
var AddComment = React.createClass({
getInitialState: function(){
return {
content: this.props.content,
adrien: "before"
}
},
handleKeyUp: function(e) {
this.setState({
content: this.refs.addComment.getDOMNode().value,
})
},
handleValidation: function() {
var that = this;
this.props.addComments(this.state.content);
},
render: function(){
return (
<div>
<textarea onKeyUp={this.handleKeyUp} value={this.state.value} ref="addComment"></textarea>
<button onClick={this.handleValidation}>submit</button>
</div>
)
}
})
var CommentList = React.createClass({
render: function() {
return (
<div>
{this.props.comments.map(function(comment){
return <CommentListElement key={comment.id} comment={comment} />;
})}
</div>
);
}
});
var CommentListElement = React.createClass({
render: function() {
return (
<div>{this.props.comment}</div>
)
}
})
React.render(<CommentSystem/>, document.getElementById('container'));
Hope this helps.

I have a Rails app using React posting to my db using an ajax call. How do I handle the redirect?

So I have my Rails app trying to submit a cohort to the database. I can get it to post to the database but I do not know how to handle the redirect.
var NewCohort = React.createClass ({
getInitialState: function() {
return {name:'',description:''}
},
handleNameChange: function(e) {
this.setState({name:e.target.value})
},
handleDescriptionChange: function(e) {
this.setState({description:e.target.value})
},
handleSubmit: function(e) {
var that = this
$.ajax({
url: '/cohorts',
method: 'POST',
data: {
name: that.state.name,
description: that.state.description
},
success: function(data, success, xhr) {
console.log(data)
}
})
},
render: function() {
return (
<div className="container">
<h3>Create a new cohort</h3>
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.name} onChange={this.handleNameChange}/>
<input type="text" value={this.state.description} onChange={this.handleDescriptionChange}/>
<input type="submit"/>
</form>
</div>
)
}
})
Is my ajax call which I send to my controller which has
def create
#cohort = Cohort.create(name: params[:name], description: params[:description])
render component: 'ShowCohort', props: { cohort: #cohort }
end
Which in my ajax success function, the data is the new React html code. How to I actually redirect the the page?
This is my React component to render
var ShowCohort = React.createClass ({
render: function() {
return (
<div className="container">
<h3>Hello {this.props.cohort.name}</h3>
<p>{this.props.cohort.description}</p>
</div>
)
}
})
Don't use ajax. Just use a regular form.
this should be like this
success: function(data, success, xhr) {
window.location.href = "redirect_url";
}
you can pass it as json as well like this in your controller
render json: {"redirect":true,"redirect_url": apps_path}, status:200
success: function(data, success, xhr) {
window.location.href = data.redirect_url;
}

React-router: component undefined

I've been running through the react-router tutorial found here and I'm currently puzzled...
React-router doesn't recognise my component.
(I'm using React.js with Rails)
Here's the code:
var DefaultRoute = ReactRouter.DefaultRoute;
var Link = ReactRouter.Link;
var Route = ReactRouter.Route;
var RouteHandler = ReactRouter.RouteHandler;
var App = React.createClass({
getInitialState: function () {
return {
showTags: false,
current_user: this.props.current_user
};
},
_handleToggleTags: function() {
this.setState({
showTags: !this.state.showTags
})
},
render: function () {
return <div>
<Header
onToggleTags={ this._handleToggleTags }
user={this.props.current_user}
/>
<RouteHandler/>
<div id="images">
<ImageBox/>
</div>
</div>;
}
});
var routes = (
<Route name="app" path="/" handler={App}>
<Route name="tags" handler={TagsBox}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
If I move TagsBox before App it works, though nobody else seems to be doing this. What am I missing?
If it makes a different, the current structure of my components is:
app.js.jsx
Tags
_tags_box.js.jsx
In your position it seems best to run the router once all scripts are loaded.
Try wrapping the run method in this code:
document.addEventListener("DOMContentLoaded", function() {
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
}

React.NET uncaught TypeError: undefined is not a function

I am trying to learn ReactJs and found React.NET.
Followed the tutorial on the author's website with the only change being an MVC 5 app instead of MVC 4.
Here is the jsx:
/** #jsx React.DOM */
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
<CommentForm />
</div>
);
}
});
React.renderComponent(
<CommentBox data={data} />,
document.getElementById('content')
);
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return <Comment author={comment.Author}>{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 data = [
{ Author: "Daniel Lo Nigro", Text: "Hello ReactJS.NET World!" },
{ Author: "Pete Hunt", Text: "This is one comment" },
{ Author: "Jordan Walke", Text: "This is *another* comment" }
];
It gives this error:
Uncaught TypeError: undefined is not a function
Any clues on this one?
Regards.
There are three steps in the snippet.
First, define the CommentBox:
var CommentBox = React.createClass...
Second, render the CommentBox and the CommentList:
React.renderComponent...
Third, define the CommentList:
var CommentList = React.createClass...
So, the problem is that the CommentList is rendered before the CommentList is defined. If the last two steps were switched around then it would work fine. The CommentList class needs to be defined before it can be rendered.
CommentForm is also defined in the wrong place - it needs to be defined before it's referred to. The React tutorial has it the wrong way round: http://facebook.github.io/react/docs/tutorial.html
The correct order for the definition of the classes in the Javascript is:
var Comment = React.createClass
...
var CommentList = React.createClass
...
var CommentForm = React.createClass
...
var CommentBox = React.createClass
...
I had this happen whilst working through the tutorial and found that declaring the var data = [...] at the top of the jsx script resolved the issue. So it would appear that the engine is not hoisting variables properly?

Resources