React has this intended/unintended side effect of teaching functional programming concepts without making it obvious.
For me, after finding out the core concepts of React (views are pure functions, functional composition etc.) are actually functional programming applied tastefully to rendering, I finally realized the elegance of functional programming, and since than I've been merging these concepts into my programming methodologies.
I think that's a big win. With React, you can see the use for functional concepts without having to switch to a functional programming language, or completely divest your codebase of 'friendly' object oriented techniques like class structure and subclassing.
Similarly, I'd give a shout to MobX for showing me how observables can be used in practice. For the longest time I'd wanted to learn it, but I'd choke on the syntax and the generality of common libraries. Showing how MobX worked to simplify React code, gave an instant sense of success and things clicked afterwards.
MobX makes React simple because it's JavaScript. If you've write React with ClojureScript, you will find out that ClojureScript simplified React too. And people may also say ClojureScript is the magic piece that make React great.
I'm saying MobX is not the final answer for React. Behind React is the theory of uni-directional data flow. Observable in MobX looks nice and it fixes uni-directional data flow in JavaScript syntax of assignments. Seeing from ClojureScript and other languages that implemented persistent data structure by default, MobX is just a tricky solution designed for JavaScript. And ClojureScript handle uni-directional data flow well too with persistent data and atom type.
Ah I see. I wasn't saying it is the final answer. It's just a 'good thing' because without it I wouldn't have learned observables to the depth that I did.
It's a start... because it brings the concept to Javascript, a language that I'm already familiar with and have a build chain for.
If one is going to switch languages, then you can consider the whole sweep of compile-to-JS languages. Elm is pretty nice in that scenario, and pairs well with my use of Elixir on the backend.
I'm really interested in Elm, it's on my 'things to explore' list. But I've already built a big 'component' library for my designs and style in React, and it's hard to justify a switch to anything else for a long time.
And sadly that's the biggest problem the upcoming languages/frameworks face.
Nothing wrong with that. I'm on a greenfield project with no particular deadline, so I chose Rust + Elm, but if I had to build rapidly, or had already committed a bunch of code in another framework, I'd definitely stick with that.
Do you mix React and Knockout components by any chance? We are looking at moving from Knockout to React and I was wondering how painful this would be. My guess would be that if you are doing all or most of your KO stuff with components, then the switch shouldn't be too bad.
I've done some mixing of Knockout and React. We had a custom datagrid that was taking a long time to bind up all the data with templates. I think it was made almost 8x faster for rendering moving it to a React component. This was a POC project done probably 18 months ago.
I've used ExtJS, Backbone, CanJS, Angular, Polymer and React commercially.
To me, React is a more complex alternative to Google's Polymer framework.
In React, a component is made up of code which has HTML inside it.
In Polymer, a component is made up of HTML which has code inside it.
They're actually the inverse of each other but the result is almost exactly the same - Both libraries allow you to build components which contain other components and both provide clean encapsulation.
One of the reasons why I have a slight preference for PolymerJS is that it's much simpler and works with existing HTML concepts (they didn't need to invent a new debugging panel, a new DOM model, a new approach to CSS styling or an advanced state management architecture like Redux to make it work) - Instead, they leveraged existing web technologies. For example, Polymer provides really nice CSS style encapsulation. In PolymerJS, the <style> tag only affects the component in which it's declared (potentially including sub-components but not parent components).
It makes CSS really easy to use/maintain without actually reinventing it. You can do cool stuff like allow a sub-component's style to change automatically as you move it from one parent component to another. You don't need any special module or library or special styling logic; just a <style> tag declared at the appropriate level in your component tree/hierarchy is all you need.
That said, the React community is massive and because of this, there are tons of modules and tools around it so it's hard to beat now - It seems that pretty much every problem that React has introduced has since been fixed.
On the flip side, React's composability and generic component rendering concept allows it to be reused across many non-HTML platforms, including React Native, ReactVR, and more (per this list of React renderers: http://iamdustan.com/react-renderers/ ).
Also, fwiw, Facebook didn't invent Redux, Dan Abramov and Andrew Clark did _before_ they joined the React team :)
There is nothing inherent to React which makes it easier to render on native platforms. This could easily be achieved with Polymer too - It's just that the Polymer community is much smaller so they're behind in that respect.
> You can do cool stuff like allow a sub-component's style to change automatically as you move it from one parent component to another.
I don't like this at all. I want all the styles to be encapsulated to the component only. It shouldn't matter what parent component it's in. Polymer's CSS automatically spills over into the child components.
You CAN optionally have styles from a parent component affect child components but you can also restrict the styles to the host component only (excluding children) if that's what you want.
I find that often though, I like the host component to affect the style of child components - For example, let's say we have 2 container components which hold a list of items; one container component shows its items as rows and the other component shows items as thumbnails (with a picture). In this case we want the parent container component to affect the style of the child item (thumbnail vs row). If we were to drag an item from one container and drop it into another, we would want the style (thumbnail vs row) of the new parent container to take effect on the child (without having to imperatively update styles in the child).
The danger in traditional (non-WebComponents) CSS is not the cascading aspect of it; it's the fact that it's global. If you localize CSS to components such that it only cascades downwards in the DOM hierarchy, then it solves all your problems.
Also, because of the CSS specificity rule, style properties defined in the child will overwrite those from the parent, so the child always gets the last say about how it looks - With this approach, the child can effectively decide which CSS properties its parent is not allowed to modify.
My team is moving from React to Vue precisely for many of the reasons you are pointing out. We considered Polymer but we felt it's still too early for web components. Vue's code is not as elegant as React or others, but it's very pragmatic, fast, lightweight, and easy to learn.
React comes with its own syntax to build components called JSX. In JSX you can mix up HTML and JavaScript. Additionally people often use inline styles in their elements. It is like adding CSS into the mix.
This really scares me. We spent a lot of effort removing inline styling from HTML with CSS, and yet it still creeps into our HTML. We also have created a lot of <program language dejour> "template" languages (e.g. PHP, Python, ERB, etc.) mixed in with HTML, which also tends to end badly (logic buried in HTML that is hard to find and hard to reason about).
How does React solve the "everything mixed into HTML" problem? Are we going down the same path that ended badly last time?
As mentionned already, and as Pete Hunt famously talked about in "Rethinking Best Practices" (you can find it on youtube), you want to separate -concerns-, not technologies. Often there is a 1:1 between those things, but not in modern web development.
So we've seen a push toward components that mix technologies, but separate concerns. And it's been great.
People learnt that mixing behavior and presentation was bad but that was a specific case of a more general rule.
In fact - "separation of concerns" is itself a specific example of an even more general rule which is something like "Make code easy to reason about" or "reduce side-effects" or similar. It's hard to give advice that doesn't sound hand-wavy and empty without getting specific. But as soon as you get specific you exclude alternative solutions to the same core problem.
Programming is largely about managing complexity and there are many ways to achieve that. But learning how is a subtle art indeed.
We usually take all software design principles at a face value and rarely think about the reasons why we have them in the first place.
The reason why we need software design principles is because software changes. Software design principles are methods of organising software that make it easier to implement changes.
When it comes to changes it seems that the golden rule that makes things easier for humans is: things that vary together should be together (and things that tend to vary separately should be separate). Its interesting to think about why this is the case, but I'll skip that and take it as an axiom.
There was an article (which I can't recall the URL of) that argued how all the SOLID principles stem from this basic rule.
Single responsibility principle: it follows directly from the above rule: A class should have only one reason to change (keep things that could change separately separate)
Open/closed principle: Interfaces should vary significantly less than their implementations, so that both producers and consumers of those interfaces can vary independently of each other. e.g. Shape can have a method draw that takes a canvas interface: now we can vary both the canvas implementation and the different shapes independently.
Interface segregation principle: don't put too many things in an interface, they might vary differently. Make separate interfaces based on consumer types since change in consumers are more likely to affect changes in the interfaces they use, and having one interface for two types of consumers means two separate sources of change that vary differently.
Map / filter vs for loops is simply this principle applied in the small. The code to initialize an empty data structure, iterate through all the elements applying a function and then store the resutls in the data structure is always the same. The only thing that changes is the function that defines the transformation. Since its a concept that is very common and never changes, it should be separated from the transformation itself (which changes often and depends on the problem domain) and be given a common name (map)
It then follows easily that separating the component template from the code that manages component state doesn't really help. Its fine in server-side languages where the template is simply the final function in the data transformation pipeline for that request, with multiple potential views on the same data (html, json, xml etc). However, on the client side most of our code manages changing state closely tied to the DOM based view: for example, the sort column and sort direction of a table, or the current item selection, etc. The kind of state we keep is directly tied with how we present things (sortable table? => sort column and sort order; expandable tree? => expanded/contracted state for all branches, etc). As our view/component requirements change, the state we keep for it (and the way we manage it) also changes.
And since things that vary together should be together...
This is just rhetoric. The notion of separation between information, presentation and behavior couldn't be any more fundamental. But instead of developing this idea any further most web developers had traditionally settled for something "easy" and complicated (i.e. JQuery that dictates all of the three things I mentioned).
In the long run, the SPA craze will backfire, big time. Rect components are not semantic and not declarative. There is no way to examine them without executing code. This is an elephant in the room most fronted developers willfully ignore right now.
I'm with you on 'declarative' but I'm always sceptical about 'semantic'. Its meaning is vague, its benefits somewhat ethereal and its actual existence in the real world a matter of rumour and speculation.
If you can pin down your definition then I'd be able to provide a more concrete opinion.
> The notion of separation between information, presentation and behavior couldn't be any more fundamental.
Fundamental to whom? Outside of web development this separation was never fundamental - see the post above regarding "separation of concerns" - which is a much better candidate for a "fundamental principle"
Why not separate concerns AND technologies at the same time. Concerns for the logical organisation of the code and technologies for easier editing of the same code.
This sounded scary to me at first, but in practice I've found it to be the opposite.
Separating css, html, and js makes sense when you're writing a document, and the content is the html and the css is strictly formatting.
It makes less sense when you're writing an app, and the styling of the html is an integral part of what is being created. The javascript works the same way; it's often integral to what's being rendered, not just patchwork adding small amounts of functionality to an existing document.
But probably most importantly is that react gives you a different way of separating concerns: it's very easy to put different chunks of the UI into different components/files, so your app is divided by functionality, instead of divided by technology. Keeping the html (and sometimes css) with the js that uses it helps increase the cohesion of small units in your UI that intimately work with each other, while separating those from other js/html/css for other units.
It switches the axis of concern from separating out the different classes of code (HTML, JS, CSS) to separating out the functional goals of your code (Component A does this specific thing, Component B does that specific thing). Realistically, the triad of front end technologies are tightly coupled, regardless of whether they're in the same file. If you can keep your components nicely bounded, then it's far easier to have them be self-contained.
It's transitioning from "document-based" reasoning to "component-based" reasoning.
Preferably, all local concerns of a component (not referring to the React component class but the abstract component: a single unit within a larger project) would be in one place. For the front end of a web app this includes structure, styling and behavior. So it makes sense to define the structure (HTML), styling (CSS) and basic behavior (animations, different states it can exist in, etc.) in one place.
React models this using JSX, inline CSS (or CSS loaders) and the React component API.
You have to ask yourself why we were removing inline styling and inline JavaScript. There is a performance argument (inline styles perform badly), but the main goal was maintainability.
Now we have ways to use these patterns and still have them be maintainable, which means it's time to reevaluate that previous effort. Co-locating styling with structure and behaviour tends to make our lives easier.
I can go one step further, I work on a React-based website which achieves straight 'A's on webpagetest and scores 100 on Google Pagespeed (Mobile and Desktop), this took far less effort than it ever took me to achieve worse results on previous stacks.
The component model (with co-location of styles) is incredibly powerful, and it works, give it a try.
Splitting your code across technology boundaries is a misapplication of "separation of concerns". The "component" concept of React and other front-end frameworks seems to be a much better abstraction.
Styles work very well on the per-component level. The best and worst part of CSS is the "cascading" part.
The thing is that with React, you aren't really writing HTML. Sure, JSX makes it look like it, but it's not a template, it's actually just a Virtual DOM element tree. This means it doesn't have the same issues as many templates.
There never was any separation of concern. Just because the HTML, JS and CSS were in different files don't mean they were truly separated. React embraces this fact and it's extremely refreshing. Each component's HTML, JS and CSS belong together.
> logic buried in HTML that is hard to find and hard to reason about
That's a complete non-issue with React and much more an issue of the traditional way of breaking it up in different files which look separated but in reality are extremely entangled.
I look at JSX as more of a helper to lower the barrier to entry. In the end it's all just Javascript. You can render the (virtual) DOM in React without using any JSX/HTML syntax. So it's not "everything mixed into HTML", it's "there is no HTML until the top-level render() is instantiated".
Also, regarding the CSS questions, setups like CSS Modules in a Webpack build make the CSS very maintainable. Not to say there aren't drawbacks, but IMO having the classes be dynamic makes everything way more flexible. And, tools like hot-module-reloading make front-end development so much more enjoyable.
I'm not so worried about it. The CSS is self contained these days in "components" where it doesn't leak out everywhere, which was the overarching problem with CSS from the beginning. Looking at UI platforms historically it's pretty standard for UI components to style themselves, it just wasn't realistic to do on the web until webcomponents started becoming reality.
Styling is syntactically really just markup decorators after all, although CSS may end up Turing complete if it isn't already :) (this is probably a bad thing)
Problem with everything in HTML was that you couldn't split HTML into small meaningful composable parts.
JS is actual programming language an you can split out styles to separate style library without using .css files.
You could also split out render function (that uses JSX) or its parts to separate file. But you'd rather keep it close to logic that interacts with it and keep the whole component, logic plus presentation small enough to understand with a glance.
Take the CSS for an small button and add all the variations you need. And after some time someone not so skilled like you arrives and adds a padding to the first button.
That on scale it's not easy solvable.
And that's the reason why we are looking for other approaches to isolate/share the main functionality.
I find it hard to switch away from React to another similar library/framework simply due to the community that surrounds the "React ecosystem". Having worked on applications using Angular and Vue, I've just had such an easier time solving my problems when using React because there just seem to be more man-hours sunk into developing best practices, which naturally leads to more mature libraries, frameworks, solutions, etc.
There are many things that the "React ecosystem" has taught me that I can apply to any future application I build regardless of the stack, but many of my problems were solved in little time because the SO answer to my questions also used React, or the answer came in the form of a React component I could plug in and not worry about.
Maybe when Vue's community is as thoroughly developed I'll try that out again. Right now it's hard to find a reason to switch.
For me, the conceptual simplicity of React (and associated projects) makes it very easy to reason about code written with it. If you've worked on a larger Angular project, you know this is a huge win - keeping things simple there requires a disciplined developer with a good understanding of Angular (a rare combination.)
Just a bug report: In the end of the article Mr. Rwieruch offers a free ebook to those that join his mailing list, unfortunately that does not happen.
You are instead sent (after confirming your email) to a site that lists the 'minimum price' of the book as free, gives you a price slider that cannot go bellow 14.99 (and the "additional information icon" when hovered, shows a minimum price of 14.99, contradicting the page's own previous claim)
A resolution that allows other users to aquire the free ebook is preferred, but removing the offer of a free ebook would also solve the problem.
Hi josinalvo, can you try the page again? As a student, the eBook should be pay what you want. You are the first person who reports the issue unfortunately. Sorry for the inconveniences.
How are you going to embed an app in another app/DOM without using an iframe, and how is creating that iframe going to be any harder to accomplish depending on the technologies used inside of it?
I'm not sure what you mean about components...Angular is component based. Are you referring to native web components?
That's one of the problems.. it only covers an slice of the front-end space. And also there is some kind of lock-in.. you can't reuse your components for something else.
My experience with Angular has been very different. I never felt pain working with Angular. Most of the issues I saw, boiled down to bad code. And I think those issues would still be there irrespective of framework used.
I also don't get why two way binding is difficult to reason about. Can somebody please give me an example?
All these discussions miss the point to me: React can be run natively on Android and iOS. Can Angular? Vue? Elm? It seems like there can't be any real competition when starting a large class of new projects until the answer is "yes."
So I'm asking: what are the best real alternatives that work natively on mobile?
How is React running natively in React Native? The most basic things are reimplemented (quite badly) in JS, such as controller navigation (for the lack of a better term), buttons, gestures, animations. Most of them run on the JS stack, which is run on a JavaScriptCore VM instance, the same VM running when using a web view. How is any of that native? For me, "native" means using only OS-native components for navigation and views, gesture handling, animations, interactions, etc., and also, do not run in additional VMs. If you are willing to let go of the last requirement, NativeScript and Xamarin are a lot more sensible "native" choices than React Native.
I think the React Native is pretty cool. React Native doesn't take your web JavaScript and turn it into a mobile app. It is using the React library with the native UI view objects.
Those are two different problems: what is the best framework for our web front-end vs what is the best framework for our iOS front-end. If you want to normalize on React for both, what is the problem that you are solving by doing that?
Almost none of the views used internally in React Native are "native". On iOS, only UIView, UIScrollView and UITextView are used, and every component is reimplemented from the JS side with some help with reinvent-the-wheel type native support. Button with highlight? JS animation on a text container view with a JS tap recognizer. Yes, even gesutre recognizers are implemented in JS, rather than using the native gesture recognizers. Animations - the same. Recently, due to great pressure from the community, some animations were added in native - and are still reinvent-the-wheel type animations, rather than using the OS-provided animation facilities. Controls already do not look or feel native, and once the OS changes its small details some more, it will require FB or the open source community to again reimplement the wheel, and then either have to support both old and new looks and feels, or only support new ones and look out of place for people that have the old OS yet (think of the iOS 6 -> iOS 7 transition, and how RN would look like on iOS 6 once they reinvented the wheel and implemented the iOS 7 look and feel).
Well, there's https://weex-project.io/ which claims to be easy the "React for Vue" you're asking about.
The only caveat is that you'd better be reading Chinese version of documentation with Google Translate, English one is basically one huge "to be done" placeholder.
Agree that NativeScript is the most "native" of the JS cross platform tools, since it can use actual native concepts, such as controllers, views, gesture recognizers, etc, whereas things like RN throw the "native" word everywhere, but actually implement everything internally in JS. A small example - a tap gesture in RN is actually implemented using `touchesBegan:` API, which routes input to JS over RN bridge, JS performs the tap logic. Doesn't sound terrible, but consider that the RN bridge is async, so the user experiences a floaty behavior, and if that single JS thread is busy with some business logic, you are dead. Same for animations and interactions. Navigation is a joke, with current and other implementations being JS replicas of the real thing, and the native NavigatorIOS, the one to use actual native iOS concepts, being deprecated.
NativeScript also has a novel idea how to implement multithreading in JS, which is commendable.
How many of you developers who use React and say that JSX is the second coming of Jesus, are also able to produce a semantically coherent HTML document with JSX?
It seems to me that React + JSX are perfect for "divitists" and devs who use a h3 because its font-size has the desired value.
I'm not being sarcastic, I genuinely can't understand why a good web developer who cares about the meaning of a HTML document should like JSX.
Well there's nothing stopping you using the right element for the job. But I would argue that the semantics of HTML, whilst useful in a publication paradigm, don't translate as easily to a web application, which is where React shines. I'd also argue that React is not a good fit for something like a blog, or a news site.
This is a great point, and a sword I fell on at my previous employer. React is great for stateful web apps - a blog or a news site have some state, but aren't really that state heavy.
Especially when you have a news site getting millions of views, you simply can't afford 1 second on page load to download, parse, and eval React and your data model for little gain.
I've seen devs that are so infatuated with React and "isomorphism" that they will use it as a hammer for every screw they come across.
I wouldn't argue that it's the second coming of Jesus, but it's been pleasant to work in. React creates HTML from JavaScript, and JSX is a convenient, intuitive, and familiar way to express your code.
I've found that React generates trustworthy HTML, letting me focus on business logic and the interesting parts of development. I've never come across a scenario where React threatened the coherency of my code (other than the data attributes that are now optional, thankfully).
I must be completely missing your point. React supports the vast majority of html elements. There's nothing I can think of about React that would encourage someone to misuse html, you're using the exact same tags you'd be using to create a vanilla site. The only difference is that you're declaratively defining how they change based on state.
A good html developer will still use best practices when using React, a bad one won't. What's the difference?
I don't know, I have yet to stumble upon a React developer who doesn't just use divs and spans for everything and who doesn't choose headings because of their font size.
That's why this question began to slowly form in my mind.
I think some people just don't get React. The beautiful thing about it is that it's really simple. Yes you create components but it's not just about components. The idea that you can treat your app ass a function and just feed it one global state is what makes it so powerfull imo. That being said there are a lot of paradoxes with react. For example it was created with functional ideas in mind and the functional comunity loves it, but at the same time i have the impression that the facebook deeloppers building it just didn't got it for a long time, and its still sinking in. Just looking at how there are classes for everything and all. It looked mor OO at the begining. And the whole flux, one would think they dont't understand the power of simplicity completly. Then there is the problem of finding the correct patterns to work with it. A lot of times you have OO people that start writing js software and when you look at the code they produce you feel like crying. Then they blame react because they just don't know how to think different.
Surprised that a blog post is published this year that is about moving from AngularJS (v1) to React. That's not really that big of a shock, lots of devs are doing that. A better comparison is Angular (v2+) vs. React, and it is really a good fight that boils down to whether you want a framework, or you want the freedom to build your own from specific parts.
I'm glad this conversation continues to evolve, particularly now that Angular(2?) has stabilized.
Practically speaking though, I'm evaluating high-level frameworks like Blueprint, Clarity, and Element, vs. the prospect of becoming a bespoke framework provider myself (probably not).
If I'm starting off with a respectable set of components, then I can adapt to the lower level libraries as necessary.
I have experience building a mobile app using Ionic framework. Ionic uses Angular for its view library. In my opinion, one thing that I dislike about Angular is documentation. I think Angular has lack of documentation. It has short explanation and no examples/use case for that function. I don't know if the documentation has changed since then because I built that app in 2015.
Now, when reading Hacker News, a lot of people post about React. I have never learnt before. Maybe, I am late to the party. I must dig posts about React to know its use cases.
For me, after finding out the core concepts of React (views are pure functions, functional composition etc.) are actually functional programming applied tastefully to rendering, I finally realized the elegance of functional programming, and since than I've been merging these concepts into my programming methodologies.