I'm trying to use react-rails to create a UI for an existing rails app. I want to make a dynamic todo list which is populated with data from my rails backend. I'm passing the tasks to the component through an erb tag provided by the gem 'react-rails'. This should make the data available as a prop for me to use, but when I try to render it in the JSX, I get an
Uncaught TypeError: Cannot read property 'tasks' of undefined
error message in the console for the line
for (var i = 0; i < this.props.tasks.length; i++) {
Here's my code:
The React(rails) component
class TodoApp extends React.Component{
render() {
return (
<div className="card col-6">
<div className="card-header">
<div className="float-rights">
create new button
</div>
</div>
<div className="card-body">
{
(function(){
var html;
for (var i = 0; i < this.props.tasks.length; i++) {
html += this.props.tasks[i]
}
return html;
})()
}
</div>
</div>
)
}
}
The ERB/HTML view it's rendered in
<%= react_component('TodoApp', tasks: @collaboration.tasks) %>
Ideally the loop would run and I would get some output.
You could get your IIFE working by binding this
from the outer scope,
<div className="card-body">
{
(function(){
var html;
for (var i = 0; i < this.props.tasks.length; i++) {
html += this.props.tasks[i]
}
return html;
}).bind(this)()
}
</div>
But this is not idiomatic React. The following is,
<div className="card-body">
{this.props.tasks.join('')}
</div>
If the tasks are in html format as indicated by the name of the variable you have used,
<div className="card-body"
dangerouslySetInnerHTML={ { __html: this.props.tasks.join('') } }>
</div>
With this approach you have to sanitize the tasks to prevent script injection and you also lose the benefits of react such as event binding. It is not recommended