Reputation: 14428
I'm currently making the change from Angular routing & client-side rendering to React & Flux for isomorphic builds. I've just started learning React so bear with me.
Here's my problem. To render a simple list, it would look like this.
HTML, component & render in React:
<!--html-->
<div id="mount-point"></div>
<script type="text/jsx">
//component
var List = React.createClass({
getInitialState: function(){
return {
items: [
"Apples",
"Broccoli",
"Chicken",
"Duck",
"Eggs",
"Fish",
"Granola",
"Hash Browns"
]
}
},
render: function(){
return (
<ul>
{
this.state.items.map(function(item) {
return <li key={item}>{item}</li>
})
}
</ul>
)
}
});
//render
React.render(<List/>, document.getElementById('mount-point'));
</script>
Or in Angular, with a controller and HTML:
<script>
//controller
app.controller("MyController", ["$scope", function($scope){
$scope.items = [
"Apples",
"Broccoli",
"Chicken",
"Duck",
"Eggs",
"Fish",
"Granola",
"Hash Browns"
]
}]);
</script>
<!--html-->
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
Now to me, the Angular code looks a lot shorter and more readable. The HTML where data is injected is not infiltrated by javascript code. I'm not trying to start a React v Angular debate. Instead, I'm wondering if there is a way to combine the best properties of both? i.e. have the stateful component concept from React but instead of using raw javascript in the JSX
, using things like Angular's ng-repeat
. If not, is there another way to approach writing the JSX
in my example?
Upvotes: 1
Views: 162
Reputation: 3172
You can actually interoperate Angular and React using https://github.com/bcherny/ngimport. We've used it successfully on a 10k file hybrid Angular+React project - let me know if I can answer any questions!
Upvotes: 0
Reputation: 18556
IMHO, the React code is better and more readable because it is just javascript. It doesn't require (hardly) any extra knowledge to understand what's going on. You read the angular one, and if you're not familiar at all with angular, you're immediately wondering: what's $scope? what's app? what's controller do? why do i pass it an array and why is the second argument a function? what calls this function? what's an ng-repeat? this list goes on ...
Now, on to your question: No.
The JSX you've written is perfect (well, sort of, I'll add my modifications below). Why is it perfect? It's perfect because nearly any programmer on the planet can figure out what it does: it maps over a list of items.
Now, if I were to rewrite it, I'd do something like this:
var List = React.createClass({
...
renderItem: function(item, key) {
return <li key={key}>{item}</li>;
},
render: function() {
return <ul>{this.state.items.map(this.renderItem)}</ul>;
}
}
Creating a separate renderItem
function to render the item will make this a lot more future-proof (and readable IMO). Also, you shouldn't put your key
as the item itself, because (in this example) that would prevent two items from having the same value (ie, two "Apple"s)
It seems like maybe what you're really asking is, "directives in angular are cool! why doesn't react have directives? and can/should I add directives to React?"
If I were to address that, I'd say... directives do seem cool in angular. Although, there's clearly some big problems with them, even the angular team abandoned them (custom ones anyway) in angular 2. There is some react library on github floating around right now that adds ng-like directives to JSX, but I highly advise against it. It's really just a bad idea. I'm going to repeat this for double extra super clarity: It's a bad idea. What's wrong with writing plain old javascript and rendering it with JSX handlebars? Do you really need an ng-repeat
because writing list.map
is too hard? The added complexity and learning curve, however slight, far outweighs the benefits. render()
is a beautiful pure function, let's leave it that way.
Upvotes: 1