8 ms·
Honest question here from someone new to React. Isn't the way it mixes in HTML, CSS classes and JS altogether something we were trying to get away from a few ye
by unklefolk 12y ago
Honest question here from someone new to React. Isn't the way it mixes in HTML, CSS classes and JS altogether something we were trying to get away from a few years ago? It feels a bit like old school ASP! I'm not trying to be flippant, I just was always taught about separation and mixing HTML markup with JS logic seems like we are going the other way.
- dagw 12y ago'We' never really came to an agreement on that question. Some people always thought it was a pretty good idea to keep things that belong together close together and some people didn't. The separation people have been dominant for a couple of years, but a bunch of people didn't really like that approach and are now taking a new stab at finding a new solution the problem. It's just two different schools of thought and really comes down to personal preference. Fashion ebbs and flows and what was old is new, and what was new is old.
- Swizec 12y agoAs someone a bit less new to React. This is leaps and bounds better than the Angular approach. My favourite part is passing functions and complex objects as element properties. Very useful.
- skrebbel 12y ago> Isn't the way it mixes in HTML, CSS classes and JS altogether something we were trying to get away from a few years ago? That's a best practice for web sites. If you're making a website (where every page has roughly the same look and structure, but just different content), then it's probably a good best practice to have. It all went haywire, however, when using the web for applications. While well-designed applications also have commonalities to them (button styles, margins, etc), the various screens and dialogs in an application vary way more in structure than the various pages on a typical informational web site tend to do. It turns out that separating logic and presentation in web applications the way you would on web sites is a very bad match. You simply end up putting logic that is very closely tied together in three different places. E.g. typical jQuery code that falls apart the moment you change either the HTML (turn a div into a span, whatever), or the css class names, or the jquery selector/handler code, all of which is located in different files deep in a different directory hierarchy. For each single widget in your app (button, dropdown, LoginScreen, etc), it's much better to put all that code together. And that's what React lets you do. (note that this means that you really do want to tie your styles closely to your react components too - either inside the JS or with e.g. one .sass file for each React component)
- pjtops 12y agoWhat about desktop/mobile applications - is it ok to mix your logic and presentation there?
- emehrkay 12y agoThis is a great question. The little iOS development that I've done it seems like the script and style are tied together with the markup. I think about how painful it would be adding a custom button(new behavior) to a notification on a website: you either add an event listener to the dom and listen for it to bubble or add it to the button directly(the easier option). These new web frameworks seem to be adding it directly to the dom node -- we're back to <a onClick="function('value')"> which is faster, but traditionally harder to manage. But since everything is a structured component (all of these things implement an interface) we can build them faster and worry about it on the component level and not the markup level. I've been playing with React and Riot and it is a very interesting approach. You can build things out a lot faster than you used to and that is what matters in the end. The user will not care if you separate concerns (as long as the page renders and is accessible, but that is another story).
- JustSomeNobody 12y agoNot familiar with react and barely JavaScript, but why is <a onClick="function('value')"> bad? I mean as longs as the function calls a function on another module and doesn't contain any more logic than that. The other module remains testable, and the only logic in the UI is a function call. If the interface of the module changes, sure the UI would have to change, but I tend to think people over think things at this point (my opinion and I hope it doesn't distract from my original question).
- mtrimpe 12y agoAs far as I'm concerned <a onClick="function('value')"> was bad because 'function' was a global variable reference. I don't think that's the case for React though so I'm not sure if the GP saw some other drawbacks in it (apart from the aesthetic of separating logic from presentation.)
- dada78641 12y agoBasically, the paradigm has you make small components with the JS, HTML (actually XML) together, and optionally the CSS too. The reason why this works is because the HTML and JS work together to make up the structure of your component, so there's not really much of a reason to separate them. And if your component is nice and small, there's only a small amount of HTML to worry about. The idea is to think of your HTML as a part of your app, rather than just "something that is modified by the JS".
- nicksellen 12y agoThe idea was approximately that html was the data and css was the presentation. In reality they are quite connected and you have to write the html to support how it will be presented, a change to the presentation often requires a change to the data (html), and this doesn't really make sense. I think a saner approach is to start with plain old data (e.g. some JSON) and have a function that can turn that into html/css/js. This is what react allows by using props/state as the input to the component/rendering function. It also permits you to pass complex objects as props/state but I like keeping to simple data as much as possible.
- pjtops 12y agoIf changing CSS requires changing the markup, you are doing it wrong. Look into approaches like BEM, and demo sites like CSS Zen Garden.
- nicksellen 12y agoChanging the presentation often involves more than changing the CSS alone. For example, you might have a table of data that you want to change into a bootstrap .row/.col structure. The data itself has not changed, only the presentation, and this required a change of HTML. The CSS always needs enough hooks in the HTML to do it's work, without the right hooks some things are impossible with CSS alone (or would be unnecessarily obscure/tricky/brittle). HTML isn't a general data format in the way JSON is.
- matthewmacleod 12y agoI do undestand where you come from there, but I'd view this as a bit different. React's building block is the 'component' – the idea being that this is an isolated part of the application. By its very nature, isolating a component means separating the HTML from all the other HTML, and the script from all the other script. Since components are generally quite small, it makes sense to bundle these together. You don't suffer the problems that encouraged people to separate concerns in the first place (things like have loads of interacting code that's duplicated and closely tied to structure), so it's OK to take a different approach – and I must say, in practice it works really well. CSS is a separate issue – React doesn't mix CSS into the pot at all.
- philbo 12y agoDo people generally write tests for these components? I'm wondering how the marrying of presentation and logic affects that.
- masklinn 12y ago> Do people generally write tests for these components? Sure. React even ships with testing utilities to make that easier: http://facebook.github.io/react/docs/test-utils.html http://facebook.github.io/react/docs/test-utils.html > I'm wondering how the marrying of presentation and logic affects that. Depends on the exact component. For pure components as part of bigger applications it's really quite easy, just render the component with a known dataset and see if it's got everything where things should be. Then again, that's similar to testing templates… most people don't really test their templates. For self-contained "widget" components things are a bit harder, it's similar to testing DOM-based widgets really.
- masklinn 12y ago> CSS is a separate issue – React doesn't mix CSS into the pot at all. Not quite true, ReactNative does, React supports it[0] and one of the lead devs (vjeux, gave the reactjs conf 2015 keynote) has a presentation on doing exactly that[1] alongside being the lead dev on Facebook's css-layout (which IIRC underlies ReactNative's layouting) [0] https://facebook.github.io/react/tips/inline-styles.html https://facebook.github.io/react/tips/inline-styles.html [1] https://speakerdeck.com/vjeux/react-css-in-js https://speakerdeck.com/vjeux/react-css-in-js [2] https://github.com/facebook/css-layout/graphs/contributors https://github.com/facebook/css-layout/graphs/contributors
- kyllo 12y agoJust because your HTML, JS and CSS are in different files doesn't change the fact that they are tightly coupled. React dispenses with this superficial separation and groups presentation, behavior and styling of the same UI element together. I've found it much easier to reason about.
- timepiece 12y agoBut if these individual components share any code between them, you'd still have to write the same lines over and over again for each component. So, how do you reason about that?
- lobster_johnson 12y agoThere is no reason that components can't share code. It's just JavaScript. Extract common code into libraries, mixins or even components. For example, we frequently create generic containers that modify the behavior of the child or parent. One example is a container that automatically sets its children to be "sticky" once you scroll past it. Another common parent is one that renders it's children is a modal (lightbox, dialog or similar). Another is a child component that, if you nest it into another, can notify the parent whenever its dimensions change.
- timepiece 12y agoSo you guys are basically defining a new inheritance model in your app, right?
- lobster_johnson 12y agoIt's not inheritance at all. The code sharing is across interface boundaries, not like inheritance where, say, changing a member variable can break descendant classes. Instantiating a component is just like declaring a variable.
- timepiece 12y ago
- timepiece 12y agoAbsolutely, React is in the wrong here and its methodology is a clear and direct violation of the "separation of concerns" principle. First, they came for the HTML markup and said "come on guys, JSX is just some XML on steroids. You should not worry at all" and we didn't speak up. Then they came for CSS and said "come on guys, they're just small components and the same as placing the CSS declarations via the style attribute anyway blah blah blah" and we didn't speak up. So you don't really know what's gonna be their next victim. There's a lot of revisionism and reinterpretation of best practices going on in the industry and hipsters and fanbois seem to go chasing the latest shiny and trendy object out there. Nothing we can do to help save these people! But seriously guys, have you seen any React dev code with all those CSS declarations and HTML markup over each other? I pity the ones who will be assigned maintain this spaghetti code.
- nwienert 12y agoI've actually never found myself more productive than with React, by a long shot. The reasons why mixing them together makes sense are above us in the thread, but I'd highly recommend vjeux's presentation on CSS in JS: https://speakerdeck.com/vjeux/react-css-in-js https://speakerdeck.com/vjeux/react-css-in-js I have apps in production with it you can look at the code to as well: https://github.com/reapp/hacker-news-app https://github.com/reapp/hacker-news-app
- timepiece 12y agovjeux's presentation only applies to a very specific use case at his org namely FB. I should not imitate him just because of the fact that it fitted or served FB right. We should think on our own and figure what works for us and not blindly follow FB's or any other org's lead. Re productivity, if it works for you, good for you but please don't attempt to reinterpret/bend the rules that are well established in the industry just to avoid criticism. For me, it's just an act of intellectual dishonesty. React does violate the principle of separation of concerns and "we're working on a component not a document level" is not fooling anyone. We should alert and educate people on this issue and then they can decide for themselves if they would go ahead nevertheless or stick to their guns. That's all!
- odiroot 12y agoIn my humble opinion it makes sense. At least in this direction, when (seemingly) JS code is generating the presentation layer (HTML in this special case). In contrast to Angular where we're told to put logic in templates (or just HTML files) it looks a lot better.
- Retozi 12y agoIn my opinion it is a misconception that React "mixes" representation and logic. You can _implement_ both representation and logic with React. (instead of JS for logic, and some clunky template language for representation). This does not mean that you should mix it. usually you end up with "representation" components that are "dumb", and logic components, that do not care about the representation of their children. see https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 https://medium.com/@dan_abramov/smart-and-dumb-components-7c... Just because it shares the implementation mechanism, it does not mean that they are mixed together. You can of course, but most of the time, you should not.
- jbergens 12y agoThis is a great way of separating things. We did this (or something very similar) years ago with ASP.NET and it worked like a charm.
- rudasn 12y agoKeep in mind that the notion of separation of concerns (markup, style, behaviour) mostly refers to the end result, the rendered page. Performance is a good reason for doing this. In other words, use css classes to style similarly looking elements instead of defining the styles inline (style attribute). Or use event delegation instead of adding a bunch of onClick attributes on your elements. When talking about developer productivity (ie. maintenance, new feature development) what's more important than separation of technologies is separation of concerns at the "component" level. Component in this context can be simply defined as a single file that contains all the logic required to render and manipulate a single DOM element throughout its lifecycle. What React does (as is Angular to a lesser extend) is allow you to mix markup and behaviour while developing but keep those things separate when generating the end result.
- lobster_johnson 12y agoIn addition to what skrebbel said, let me clarify that React doesn't encourage you to mix _all_ logic with presentation, only that logic which relates to presentation; everything else ("business logic") belongs elsewhere. The core idea is that presentation logic belongs with the presentation; you cannot separate the two. In classical MVC frameworks such as Cocoa, this is accomplished with a controller that is tightly coupled with its view. Most people use Interface Builder and maintain the view in a separate file, but this is purely a pragmatic design allowing IB to use a different file format from your code. You could write the entire UI in Objective-C/Swift code, right in the controller, and in terms of layering there would not be a lick of difference. React, like other MVC-bases systems, encourage the UI logic to be slim and strictly UI-oriented, and to move the application logic -- that which deals with the flow of data/state -- to a separate layer.
- ripter 12y agoI have the same feelings. That's why I like projects like http://www.ractivejs.org/ http://www.ractivejs.org/ and http://rivetsjs.com/ http://rivetsjs.com/ . They have the productivity benefits without forcing you to use JSX.
- Andir 12y agoI wouldn't say I was "forced" to use JSX. I started out building React using only JavaScript notation to build the DOM (React.DOM.div, et al.) because I told myself that XML formatted text doesn't belong in my JavaScript. I then started to use JSX. It's a beautiful thing to get into if you give it more than a cursory glance. For one, readability is incredibly better with JSX and passing data becomes less of a chore.