While I'm not entirely sure what the original reasons were, I can see a big difference between the way, say, PHP was embedded in HTML and now JSX is embedded in JavaScript:
1. PHP was embedded in HTML, not the other way around.
2. The preprocessor basically concatenated everything as strings without caring about what DOM would end up being a result.
Because of these two reasons it was extremely hard to protect against improper injection of data into the resulting HTML. There was no way to make the preprocessor understand the different types of "placeholders" in HTML and what kind of data should be allowed within them.
In contrast, JSX embeds HTML within JS. Furthermore, JSX (pretty much) compiles to function calls, not string concatenation. This means that the engine has great degree of control over the interpretation of the data: its impossible to get malformed HTML, or for an attribute value to escape the actual attribute and so on. Which in turn eliminates the original problem that was present in PHP.
As for separation of concerns, thats still possible with JSX. We have CommonJS (or ES6) modules and we can move the render functions anywhere we want. But now its up to us to decide whether it makes sense or not.
Graphic designers were expected to know HTML/CSS while developers focus on PHP.
React components only ever contain view logic, which already solves a part of the problem. Furthermore, you typically split that logic into multiple components, many of which are stateless, independent and small.
Apart from here it is again...
So...like PHP, then?
No, because PHP still work that way (hypertext pre-processor) and Yes because, PHP has frameworks that makes PHP work like other solutions (Ruby,Python,Java + frameworks), but one still need a <?php on top of a file.
And again, a lot of PHP developers despise these frameworks and question their usefulness. In theory, they are right since PHP is a template language which goal is to render text content, and separation of concerns can be easily achieve without a complex framework in the case of a web application. In practice a framework makes large codebases more maintainable, no question.
PHP is a strange beast. It's somehow rigid like Java, at least more rigid than most dynamic languages, it's a dynamic language, and a template language and it keeps on getting stuff from Java like languages (PHP 7).
It's ironic that PHP was created because its author kind of found Perl too difficult to use for web dev, then wasn't taken seriously by pros then tried to imitate Java in some ways to feel more professional and now is on part with Perl in terms of complexity, while half of the PHP community praises over engineered codebases often found in the JEE world.
I can't dump html into a .rb or .js file, so I'm less likely to do so as a beginner. On the other hand, starting out with php, that seemed like the logical thing to do. Because I could.
I think what the commenter is saying is no one builds like this anymore in PHP, regardless of whether or not you're using a framework.
Let me try and cover some of the reasons why. I'm sure you know about these reasons (and can probably list more), my goal is just to present an example of what I consider to be a straightforward logical explanation:
If domain/business logic is mixed with view logic, then it would not be possible to reuse the same logic in a different view. These changes happen more often than anticipated: for example, a PHP project that has the view logic separated from the domain/business logic can more easily get an API (a HTML is one view, a JSON API would be just another view)
Additionally separating database code from business logic lets you switch databases more easily or to give you multiple ways to access the data. For example, data may be directly fetched from an SQL database initially, then its determined that this is too slow and results need to be cached in Redis. If there is no separate code for the data access layer, you would need to locate every database query and make sure it queries the cache first.
So this is what qualifies as a straightforward, logical explanation for me: lets assume the opposite statement was true, then we demonstrate how this leads to a bad situation and why its bad (more bugs, more work, and so on).
Another would be doing a case study: we did X (mixed business logic and templates in this way), then when we wanted to do Y (present a different view V) we had to not only write new code (for the new view) but deal with this problem (uncouple the existing logic from the existing view). If we originally did otherwise (wrote the logic separately) this would've been the same or similar amount of work (demonstrate this) yet later we would not have to do the hairy decoupling (which took Z amount of time and caused N bugs)
I think the whole industry would do much better if we focused more on actual specific examples and case studies of problems and drawbacks of different approaches rather than giving vague descriptions of the current state and claiming its "bad". Its just not helpful at all. There is so much reinventing the wheel in our profession simply because we are not communicating knowledge effectively. Frankly, most of it reminds me of religious dogma.
You need some sort of logic in your views, no matter what system you use, i. e. loops or formatting dates.
Because people are raised on the "don't mix logic & layout" maxim, they feel dirty when they write sich logic in their usual language.
.. so they invent template languages...
... that then expand to be turing-complete and basically offer everything their primary language offered in the beginning.
So you end up with a new language to learn, which is usually clunky and ugly just for the bragging rights of "not mixing logic & views". Which is completely stupid. Views can (and almost always need) to contain some logic and the best language for that is the one you're using everywhere else.
then they wrote template languages on top of the template language to separate layout and logic again ( PHP vs Twig/Smarty )
so maybe we need to step back a little and figure out how to write a language that wouldn't need a different syntax for logic and layout. This family of languages exists already, but since current developers grew up with C like languages, it is not that popular.
IMHO the best compromise is direct support for XML syntax inside languages (which Javascript had at some point with E4X) because I don't think anyone will be able to make developers use LISP like languages on a wide scale. JSX, with some modifications and standardisation could also be a solution.
Here's a function that always returns true - but it could do any kind of data access. It is just plain Clojure.
(defn selected? [] true)
Here is a datastructure that represents html: [:h2 {:class (when (selected?) "selected")} "Hello"]
Calling the function hiccup.core/html on that datastructure yeilds an html string like this: "<h2 class='selected'>Hello</h2>"
So that's great for _strings_ right? But there is an awesome library for ClojureScript called Reagent. And it uses those simple datastructures to generate react components!! I put some more examples at: http://hiccup.spaceIt helps that Clojure's syntax is based on s-expressions, and s-expressions are already isomorphic to HTML/XML.
So in a way, you're still mixing your templates and your code, but you happen to be using the same syntax for both. Which is arguably an improvement.
The ability to copy snippets of HTML from web, or old code when refactoring, or from Clojure/Hiccup to another language & framework, or changes from developer tool, or familiarity for new engineers, or not having to care about what flavor of HTML is hip today is a huge productivity boost for me.
I would love to see push for template strings [1] in Clojure, it should be trivial with macros. It would only take some time for IDEs to catch up. They're good. So good they've even influenced Python 3 to add them.
(defui my-component [x]
"<h2 class=(when (selected? x) ["selected"])>Hello</h2>")
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... (defui my-component [x]
<h2 class=(when (selected? x) ["selected"])>Hello</h2>)
It's possible to macro the above to the code below, without any language extensions. IntelliJ has powerful nested DSL introspection, it would be neat if Cursive allowed to hook into this through defui's metadata for highlighting. I was a hater of JSX until I used it. Now I hate eDSLs. :D (defn my-component [x]
[:h2 {:class (when (selected? x) ["selected"])} "Hello"])The equivalent would be something like
function() selected { return true }
["h2", {class: function() {if (selected()) {return "selected"}}}, "Hello"]
Not as clean, but still usable IMOThe worst I've seen is a bit of confusion between models and controllers. But views are usually as clean as the Gods of MVC commanded.
Not a good thing, IMO, since it makes the syntax way more complicated, but there you have it.
<div data-scope="users"><div data-attr="name"></div></div>
Now I have everything I need to process this html with my logic to turn it into
<div id="users"> <div id="user_1"> Frank </div> <div id="user_2"> Bob </div> </div>
edit: I wish downvotes required commenting on why you're downvoting.
I understood your claim fine. I'm trying to explain why it might be considered false (and I did already say I consider the arguments each way basically hair splitting).
Either way, I _think_ I have a better understand of potential conflicting views. Thanks for taking the time to explain.
It sounds to me like you are arguing that because people will put logic in templates, and this leads to ugly template languages, we should just program in ugly template languages rather than doing any separation of logic from templates.
Where I work right now, we use the newer versions of ASP.NET that come bundled with the Razor templating engine, which uses .cshtml files. You can write C# inside the files much the same way you can write JavaScript in a JSX file, it makes creating forms and such a breeze.
Big bonus is that moving from writing server-side logic to client-side logic doesn't require much of a context switch, and you can use the same objects to represent your data on both sides. If I spend all day moving between half a dozen different languages that get compiled by a dozen different tools, it can get a little exhausting.
Razor seems to have been born out of a frustration someone had with writing
return "<div>" + model.name + "</div>";
Razor is basically a DSL for C# string concatenation, where everything not escaped with an @ is a string literal to be concatenated. This means it's fairly unopinionated about structuring code. React, on the other hand, forces you to define components- ideally, pure functions from properties to JSX (which is just sugar for JS). This means composition is the default solution to everything. Razor doesn't place nearly as much emphasis on composable components, and the mechanisms it has for doing so, like helpers or calls to RenderPartial, are clunky and worlds away from the first-class component support of React.While it's technically possible to write Razor code with a React-style focus on composition, the syntax and architecture of viewmodels/templates actively pushes you away from doing so. In my experience, most Razor ends up like a C# translation of PHP, and I think that's really the paradigm Razor inherited. Razor has been around since 2011, which significantly predates the Cambrian explosion of clientside js frameworks, so it makes sense.
No you don't. Look at Wicket for how to do this right: everything is a component, the only thing[1] your templates contain is a) markup (which is 100% valid, using a namespace for the only wicket-specific part) and b) ids that indicate that a given tag will be replaced with a component. Everything else is handled by the component hierarchy in code, using proper OO polymorphism (it's also a great example of proper use of OO, with classes left with only the correct extension points, and classes or methods declared "final" if the developers don't intend to support custom ones going forwards). You end up making truly reusable components that can be very small - even something like an address input is a component defined in terms of smaller components.
I wish there were Wicket equivalents in other languages.
[1] There are a few other conveniences, but they really are minimal
> b) ids that indicate that a given tag will be replaced with a component
With that in mind, your disagreement is contradicted by this statement because logic has just been described to update the view. Logic is necessary to generate a view of the data for the user.
With JSX, keeping all of this code closer together that is intrinsically tied together increases cohesion, by definition. Subjectively, this makes it easier to manage UI because one only have too check one place for all the pieces. For further exploration of this idea, check out the intro of this video on separation of concerns vs technology. [1]
On a separate point, it sounds like one must imperatively update the UI with Wicket, which is objectively more complex than what React affords, which is stateless UI. Time is removed from the equation, which also makes things easier to reason about.
[1] https://www.youtube.com/watch?time_continue=275&v=x7cQ3mrcKa...
There is no logic in the "template". No looping, no branching. Only inert ids. There is logic in determining which component replaces each id, but that logic lies in the code, not the template.
> it sounds like one must imperatively update the UI with Wicket, which is objectively more complex than what React affords, which is stateless UI.
Not so. Wicket clearly separates its state into models, you write UI that depends on a model as a function of that model. It leads to a very declarative/functional style, where the only "magic" is encapsulated and explicitly managed. (You do have to declare which changes update which UI (for performance reasons), but you can make that "always re-render the whole page" if that suits your use case).
Again, changing view to mean "template" is a strawman.
> Wicket clearly separates its state into models > You do have to declare which changes update which UI (for performance reasons),
Separating state isn't the same as no state. Also imperatively updating the UI on state changes is stateful. Which increases complexity, which for most people makes code hard to reason about.
> but you can make that "always re-render the whole page" if that suits your use case
Anything can be made to do anything, so this point is moot. If this model was trivially applied, would it lead to flickering, lower performance, losing scroll position, losing selection, or losing input focus?
Call it what you like. The point is that clear separation between logic and markup can be done and is valuable.
> Separating state isn't the same as no state.
Any web page that has inputs or controls is necessarily stateful - otherwise where does the input go?
> Also imperatively updating the UI on state changes is stateful.
There's nothing imperative about it. Have you looked seriously at Wicket or are you just throwing buzzwords around?
You concede the original point. To your new point, saying something is valuable doesn't make it valuable. Why? It decreases cohesion, which is not good.
> Any web page that has inputs or controls is necessarily stateful - otherwise where does the input go?
If this is a serious question, it's too far off any original point to teach you unfamiliar concepts. Learn about what stateless, declaratively, & imperatively UI means so there aren't strawmans, and so you can weigh in on these discussions.
> There's nothing imperative about it. Have you looked seriously at Wicket or are you just throwing buzzwords around?
Please do not dilute conversations on here by name calling. Imperative & state are basic computer science terms... o_O
No. Your original claim was that you need to mix logic and layout. You don't.
> If this is a serious question, it's too far off any original point to teach you unfamiliar concepts. Learn about what stateless, declaratively, & imperatively UI means so there aren't strawmans, and so you can weigh in on these discussions.
It's not me who needs to learn what those words mean. Either you're just trolling, you don't understand the terms, or you don't understand wicket.
You can go the other way...just put the logic in the controller to format data and otherwise build the model in a way that is cognizant of the view. But, then you've just "polluted" the controller with the view.
One approach at solving this is frameworks like Wicket, which (in spite of shortcomings) encourages the use of view components in a way that allows them to render a more organic model. Yes, you may write some Java to render specialized components, but you're at least using the same language and being specific about writing rendering code that is also reusable.
First, in practice what everybody turned up doing was the inverse (add programming logic inside their HTML).
So you still had mixed HTML and JS, but in a way worse way: with ad-hoc and incompatible pseudo-languages (e.g. Angular's ng-repeat etc, Knockout's template instructions, etc), spiced with "JS inside HTML attributes", with no syntax checking (a typo could blow your code in runtime) and convoluted to boot.
Now, having HTML and logic together makes sense when creating widgets/components, as you have all functionality for widget in the same place. After all in every native UI framework you have instructions to draw the widget IN your code -- not as some external additional technology. A widget's C/C++/Obj-C/Swift/Java/C# etc code encapsulates everything about creating it and showing it.
So, the better way is to have all your widget drawing depending on external (or internally stored if you must) state, happen inside the widget code itself. Not to try to manipulate a string template by sprinkling ad-hoc instructions like for-each and if-then.
And here's the better part. React doesn't really mix HTML inside JS.
JSX might look like doing such, but it's just sugar for calling Javascript functions. <div> is essentially something like: React.createElement(null, "div"); So, the "HTML" is just calls to DOM manipulation methods.
So, with React there's just JS, and it handles all the creation of the HTML code for a "component" (widget). It's also composable, so your panel is just a components embedding other components.
With the notable exception of Windows. XAML strictly enforces code and markup separation. It makes the View layer more toolable and easier to edit by designers who usually don't program.
WinAPI abides...
MVVM is nice regarding testability, but I find it to be overkill for most applications.
the main difference between React and everything else is that React brings HTML to Javascript (and not vice versa). The result is code, that's easy to understand, test, develop. Code and templates should be decoupled, but in UI development, template is just the visual representation of behaviour (code), which means it makes sense to couple them. Plus when you develop in React, most of the logic should be outside of components in any case (I use Redux so it's in reducers and middleware + some util files).
(Note: I've minimal Angular experience so I won't comment on that. I've spent the last year on React)
The real problem is mixing business logic and presentation, not mixing HTML and JS. React is purely presentation & presentational logic (or should be, you can of course implement it poorly)
For Presentation, the HTML and JS are always coupled, whether you have them in separate files or not. So in that sense, all React is doing is admitting a truth.
While embracing the coupling of that mix, React is ALSO pulling out a lot of logic: React encourages one source of truth (the state is in one spot, and drives the markup, but you never consult the markup to determine the state). An error that is commonly seen in, for example, jQuery apps, is that some state is hanging around in application variables, while other times it's in the current markup state, and the app will consult the markup to see what's happening. That's not a built in jQuery problem, it's just a common problem of implementation.
I'm not sold entirely on the React boat, but it does seem to directly address problems that I've encountered in other systems, and I expect whatever comes next will build from React principles rather than reject them.
Absolutely not. Back when we were all just using jQuery, you could run $('.some-class').myWidget() to activate a widget on any element matching the query. There was no need to couple the implementation of the widget with the element to which it was applied.
If the widget had some internal element construction to do then yes, I would agree, it makes sense to have it be part of the same file, and this was often done with string concatenation back in jQuery days.
However, there is still value in being able to share the same html template across multiple models. You may have a general tabular structure you want to adhere to app-wide but you may want to implement different dynamic logic to those tables in different places. Now you're faced with having to copy/paste the same template over and over in React to accomplish the same task, or you have multiple mixins that define different behavior which kind of defeats the purpose of having the logic and the markup live together.
...which covers most everything, really. Also, in the React world, if you just need to manipulate the data passed into a component, that's all pure JS. Only the component itself (with a reference to the passed-in data) would be JSX, which is distinctly more friendly to work with than string concatenation. (and I say that as someone that hates having a build step)
> However, there is still value in being able to share the same html template across multiple models. ... > Now you're faced with having to copy/paste the same template over and over in React
I don't think you understand the concept of a React component, or I've misunderstood what you are saying. Make that template once and just use it wherever needed!
I have some complaints with React, but lack of reuse and JSX being worse than the alternatives are NOT among them.
So we have obfuscated the functionality embedded in our HTML with jQuery calls in separated files. Is this what you mean by decoupled?
> Now you're faced with having to copy/paste the same template over and over in React to accomplish the same task,
This is nonsense. Have you ever... used React? I recommend not opining on something which you lack even the most basic knowledge about.
From the side it might look like a bad practice, but I promise - this "HTML" in JS leads to fantastic testability. And I certainly prefer to work this way instead of filling HTML with numerous of "ng-" attributes where you're trying to force app generate code that you want.
Sidenote: even though it looks like HTML, it is not exactly HTML.
It is only through laziness and lack of understanding that people couple them together.
The separation that scales is the one that pairs a small piece of DOM (like a piece of text on the page that updates with the current stock price) to the JS that goes with it, and put that into a single file. Now, build your web page out of components instead.
Developing a webpage and adding progressive enhancements to HTML elements is a strongly advised best practice with numerous advantages.
Developing an dynamic application at the complexity of say Photoshop it would be absurd to have a static HTML file with behavior decorated by JavaScript, or try and offer a fallback. Whilst you could in theory perform you photo editing with form submissions and round trips to the server I am not sure it would be worthwhile (I did actually create one circa 2004).
The structure of your code does not have to dictate the result that is served to the user.
After working quite a bit with AngularJS, trying to read HTML with a ton of AngularJs is nearly impossible at times.
React is way easier to read and makes a lot more sense to my modular thinking about code. It also works naturally better for SEO compared to AngularJS.
https://www.youtube.com/watch?v=x7cQ3mrcKaY
It turns out there is no good reason to separate code and templates, because they are intrisically linked; one cannot work without the other. The separation should rather happen on units that are really independent, such as 2 separate pages of your application.
I mean it doesn't get any more straightforward than this.
<div id="app"> <p>{{ message }}</p> <input v-model="message"> </div>
new Vue({ el: '#app', data: { message: 'Hello Vue.js!' } })
It does result in a tight coupling of template and code, but I'm yet to see a downside to that. Separating template and logic has been the dream forever but is never realised in any non-simple project. Embracing that coupling has been great for me.
But more important is the separation between the directive and the rest of the code. The directive is specifically about the logic that's directly related to the view. That's not something you want to put too far away from the view.
And of course Angular's html is enriched html: by including directive, you can put databinding, and limited logic (generally about when you show that bit of html) directly into the html. Separating those would be frustrating and a bad idea. If your view is dynamic, that logic should be considered part of the view.
And of course Angular's html is enriched html: by including directive, you can put databinding, and limited logic
Either it's logicless or it isn't, surely. To me, databinding is absolutely the kind of logic that shouldn't belong in a template in the world of strict code/template separation. Another reason why it doesn't really work.
If you refuse to put the former in your view, you're making your code a lot more complex for little gain. But if you put the latter in your view, you're making your view unreasonably complex and hard to read.
Neither extreme is good. You need separation of concerns, but some logic really does concern the view directly.
Even in Angular, where we try to separate the template from its directive/controller, I don't think I've yet run into a case where I can just reuse a template with a different directive. And in fact, if I was about to do that, I should rethink my strategy (and probably just use the existing directive).
It is possible to separate JSX elements from the rest of your code if you use ES6 React components or functional components (that is, you don't use React.createClass), because in those cases there is no need to compile the components themselves, so in theory you could separate the "HTML" bits into separate, dedicated files. It's not really a problem I've faced so far, but might end up doing in the future.
JSX is just sugar for vanilla JavaScript. It's not HTML per se, as it's not parsed as such, but only as a means to create the virtual DOM.
Granted, not all recent developments are bad, of course - eg compiled & typed languages being back in "fashion" is a good development imho. It just feels to me we're either not very good at passing knowledge down or just collectively don't care much about learning history to avoid the same mistakes.
[% BLOCK foo %]
<td>[% payload %]</td>
[% END %]
...
[% INCLUDE foo payload=something %]
in TT (perl's Template Toolkit, which I'm about 98% sure pkrumins is familiar with already), and then function foo ({ payload }) {
<td>{ payload }</td>
}
...
<Foo payload={something}/>
Once you've got a bunch of them in the same file, I don't honestly find the JSX much different. The trick for me is to have the HTML in .js files that contain only pure functional rendering components - so when I'm editing those, I can think in HTML and just treat the JS as a slightly weird template syntax - at which point the squick factor mostly recedes.Basically, adding html to javascript is much more powerful than adding "some" parts of javascript to html. Every time I go back to django and need to create filters and other craps to put something in the html I feel like I'm wasting time with bureaucracy.
The alternative view is "things that are tightly coupled should live together" which I think is generally a better maxim.
In theory views can be loosely coupled, but in practice they seem to be almost always coupled 1:1 with whatever layer is above them, controllers or view models or whatever.
I can't say for Angular but the thing about React is that it is the V in MVC. The fact that JSX apparently mixes JS (logic) and HTML/CSS (presentation) is kind of a red herring. The JS logic in JSX is actually the view logic, not but domain logic!
Also, as an experiment you can prove to yourself that you can separate out all the actions, views, and states in React. Here states=model, views=view actions=controller -- but wait you say, this is MVC so React is in fact MVC and not V! No! The thing is MVC can be arranged hierarchically into levels, so you can have M(MVC)C... if you like :) Don't believe me? Check it out: https://en.wikipedia.org/wiki/Hierarchical_model-view-contro...
https://facebook.github.io/react/docs/jsx-in-depth.html
[NB Not that I know, just checking my own understanding].
It's not a text templating language like classic PHP, it's an object/function calls hierarchy DSL (more like vb.net XML literals). I think most people critisizing react for putting html in JS havn't tried it or don't remember why "html" in code was considered bad in the first place.
I'm also thinking in more of an Angular2 context as that's what I'm most familiar with.
https://babeljs.io/repl/#?experimental=true&evaluate=true&lo...
I felt the same as OP when I first started using React, although it makes more sense now I've played with it, I'm still not sure about mixing concerns (code and view) in the same file. Especially when you start talking about CSS too...
JSX is a JavaScript syntax extension that looks similar to XML.
Don't we all hate XML? How can you possibly even go on reading about this technology further if it's introduced like that.I believe people hating XML has more to do with using XML as a data transfer format, right? I'm happy using XML for Android layouts but can't imagine using it as a replacement for JSON - which I think is where most of the hate comes from.
But if you're using XML to basically make a variant of HTML, it's great.
JSX is a JavaScript syntax extension that looks similar to HTML.Separate HTML and JS? That's a small implementation detail. You can have your view layer as JSX files, separated from business logic, data access, etc. That's actually recommended.
Even when you are using purest HTML template engine, completely separated from JS logic, you still can make a mess, moving lots of logic into HTML or moving all your layers into a single JS file. File boundary is very artificial separation. It doesn't always help. And often it makes things worse, because you have to work around limitations.
Back in the day, I thought it would be a great addition to Perl if xml/html was also added to the language syntax. This was before html templating systems existed, and CGI.pm wasn't a good choice for my web application, so my code was full of print statements, quoted strings containing html, and having to use qq!...! for my quotes to avoid problems with " and ' characters in the output I wanted.
When I first saw JSX it seemed like a great thing, finally satisfying that old desire to have html markup as a native language syntax feature. I feel like it can be transformative, in the way you write your code, just like Perl's regex syntax or like having functions as first-class values can be in functional languages.
Having used React.js a bit, I'm not so sure. But I'm probably biased because I don't think React.js fits well with what I'm trying to do: ASP.NET MVC web applications that are mostly traditional full-page-refresh style apps, with some SPA-like AJAX-based interaction on some pages. I wanted to use React.js for those SPA-like pages, but it doesn't integrate well (or at all) with Razor-based server-side rendering, and in my testing it had a significant 1000ms+ startup time when the page loaded even for pretty trivial components, with caching of the React and Babel javascript files.
With "stateless functional components" (added in React 0.14) and ES6 you can have "templates" that look like this:
export default ({ title, author, body }) =>
<div>
<h1>{title}</h1>
<h2>By {author}</h2>
<p>{body}</p>
</div>
I wonder if anyone has written a linter to enforce a "logic-less" dialect of JSX? Perhaps allowing specific looping and conditional idioms like: { array.map(object =>
<div>{object.whatever}</div>
) }
and { foo ?
<div>yes</div>
:
<div>no</div>
}2) Best practices focused on separation of concerns, and in particular, on avoiding embedding logic into your static HTML. The canonical example to avoid historically was to put JS directly into a links href attribute, but some have suggested Angular is guilty of something equivalent with its ng-* attributes.
3) Conversely, React advocates agree 100% on separation of concerns, but feel the "nothing that looks like HTML can be in the same file as something that looks like JS" injunction is actually an example of separation of technologies.
The only real issue I see is that if you move HTML into JS, you might make it harder for a pure visual designer to step in and work on HTML/CSS, but outside of that I can't see an issue as long as you keep reasonability of the code in mind. And if you have a good designer, I have a feeling they'll be more than glad to learn how to navigate around Javascript.
The thing that I don't agree with about the blog post is the inclusion of State in the main App props in the form of maxSomething (forgot already the prop name) App configuration should be gathered in one place as a set of constants, IMO. App state should only contain the data, not the meta.
Whether the scope of your business can be used by this architecture would determine whether it would come up in your day to day.
These days everyone seems to think they need an application style site, and whilst some sites really do benefit from this approach, others don't.
The trinity of web standards (html/js/css) are still valid for informational, mostly static web pages, but are impractical for developing applications.
The discussion of what is a web application is a tricky one to put a finger on, with a lot of grey area. I think of a classic web page being the about us page of a website, while an application is something like photoshop. In between you have things like twitter, or gmail, amazon, facebook etc.
However, when you start giving the user powers to manipulate data and make the manipulation of data a core function of a website, it becomes a web application.
Photoshop is an extreme example of a web app really, and perhaps the most basic web app would be something like a CMS or a forum. Hence why social networks and email clients are created as apps now: they involve repeated display and manipulation of elements which are liable to change.
Initial attempts to improve the user experience of such tools as online chat and mail were made by using Ajax and this has culminated in asynchronous Ajax and virtual DOM models in order to achieve a real-time effect without sacrificing accessibility and performance.
We went from reloading entire pages to reloading bits of pages to never loading those bits but rather constructing them on the front-end drawing data from APIs.
Now with React and similar libs, we are looking at a hybrid approach: exposing data via API but (ideally) constructing and emitting HTML on the server before pushing the app to the client where a virtual abstraction of the DOM is established, but where data can still only be manipulated in one direction. This means that there is no state issue, because while routing and other interactions are achieved client-side, their composition is determined on the server.
It's almost a dialectic cycle of thesis, antithesis and synthesis.
I think a large part of the definition of "application" is subjective, personally I think social networks, such as a forum or twitter suffer from being an "application". You want to benefit from SEO, fast loading, responsive design, accessibility etc. However a chat app, that's personal and contains ephemeral content is a much better candidate for an application. I expect to see a different setup from other users, I don't want it to be searched, I expect different experiences on different devices etc.
Another good example is tweetdeck vs twitter. One is very personal and customizable, the other is essentially a generic and universal between users.
I think we are entering a phase of "everything is a single page app" because it's interesting and exciting. Similarly to the early days of mobile of flash development. Hopefully in a few years there will be a renaissance of the simple webpage, and application frameworks will be reserved for the use cases they really make sense for.
React enforces 1-way data binding and renders everything in one clean pass (HTML/CSS/JS).
The danger you run into is PHP nightmares where the programmer has e.g code that accesses and fetches items from a database in the middle of the view.
<MyComponent mySuperCoolProp={this.state.someState}></MyComponent>
This is not traditional HTML from the early days and because it is not it has a higher chance of reuse outside of just an internet webpage, and makes it easier to transfer across other view layers, canvas, native desktop/mobile views, etc
$('<div>').append($(<h1>).text('...')).addClass('...').appendTo($('#selector'));In the beginning of JS+DOM, it was a common practice to write HTML with DOM events (in JS): (`<button onclick="doSomething()">`). Server rendered most things anyway so you could (`<button onclick="toggle(<%= someId %>)">...<div id="item-<%= someId %>">...`). Problem was tons of global functions all over the place, or many big objects and maintainability issues.
In the "jQuery era", you'd write your initial HTML in .html files and jQuery all the events. It brought infinite amount of ways to write code, which often led to many styles and no conventions.
<button class="toggle" data-target="item-<%= someId %>">
<div id="item-<%= someId %>">div</div>
$('.toggle').click(function () { $($(this).data('target')).toggle() })
or <button class="toggle">+</button><div>div</div>
$('.toggle').click(function () { $(this).next().toggle() })
or worse, <button class="show" data-text="hello">+</button>
$('.show').click(function () {
var $this = $(this)
var $div = $('<div>').text($this.data('text'))
$this.after($div)
})
etc.Many problems with this approach:
- You can't tell which element has events bound to it just by looking at it. Any JS file can decide to do that - Usage of a CSS class to find elements is just a hack - Poorly named IDs/classes create collisions - After an action, the initial HTML no longer represents the current state - Server can render some HTML, then client changes it, and if things get out of sync, the only way to reset the state is to reload the entire page. Imagine a user signing in, and many parts of the page need to show things for a signed in user. Doing this manually would probably be error-prone, so it's just easier to reload the page and let the server do that.
And then came the modern front end libraries/frameworks like React, Angular, Ember etc.
The main difference is that now the HTML representation is ALWAYS in sync with the data, AND the functional code that's attached to each element is at the same place.
And the jQuery example becomes this:
// react
<button onClick={::this.toggle}>+</button>
{this.state.isVisible ? <div>div</div> : null}
toggle() { this.setState({ isVisible: !this.state.isVisible }) }
// angular 1.x
<button ng-click="toggle()">+</button>
<div ng-if="isVisible">div</div>
scope.toggle = () => scope.isVisible = !scope.isVisible
When you look at this piece of code you immediately understand the ways it can be rendered and what affects it. Super clear, no surprises.everyone else please stop replying
Everyone please keep replying.