Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with React.js #1439

Closed
while0pass opened this issue Jun 21, 2014 · 9 comments
Closed

Integration with React.js #1439

while0pass opened this issue Jun 21, 2014 · 9 comments

Comments

@while0pass
Copy link

Are there any plans to integrate knockoutjs with react.js https://github.com/facebook/react ?
Seems like it could improve rendering performance in some use cases.

@mbest
Copy link
Member

mbest commented Jun 22, 2014

Knockout and React don't seem like a good fit for each other.

@SteveSanderson
Copy link
Contributor

If anyone has specific integration suggestions, or preferably samples, let us know!

Until then I'll close this for tidiness.

@brigand
Copy link

brigand commented Jun 27, 2014

I use Knockout and React (separately), and have a decent understanding of the internals of each. There's really nothing you can do to combine them at the library level. The reason is Knockout takes DOM as an input, and manages that; while React takes its own data structure as an input, and produces DOM. They're incompatible implementations, but that doesn't mean you can't use them together in your code.

For users you can do things like write a few components in React and use a bindingHandler to incorporate it in Knockout.

var render = function(el, value){
    React.renderComponent(el, MyReactComponent({
        data: ko.unwrap(value),
        onChange: function(newValue){
            if (ko.isObservable(value){ value(newValue); }
        }
    }));
}

// ...

init: function(element, valueAccessor){
    render(element, valueAccessor());
},
update: function(element, valueAccessor){
    render(element, valueAccessor());
}

I forget how valueAccessor works in 3.0, so this is probably wrong

It's more difficult to go the other way and embed a Knockout template inside React (you'd need it as a HTML string, but you can do it).

You can also power a React application with Knockout observables, which can be very powerful. Here a mixin might make sense to automatically apply the new observable value to your component's state. This will let you use existing view models in React components if you like.

Keep in mind that react is often very fast, but Knockout also has some similar optimizations, so it's usually not worth rewriting code unless you have noticeable performance issues.

@ZiglioUK
Copy link

ZiglioUK commented Feb 3, 2015

That's a clever example @brigand

@claudeduguay
Copy link

I'd like to comment on the idea of integrating React and Knockout as I'm not sure they are as diametrically opposed as this thread suggests. Keeping in mind that I am just now studying React and the Flux architecture but it seems, at least at first glance, that React doesn't try to be anything but the View and is based, at least in principle, on reactive functional programming, Knockout is reactive in the sense that it propagates changes from the view model using a pub/sub model.

I've been using Knockout in large, single page applications for about 18 months and I've read virtually every book and blog I can find. For React, I've read all the documentation on their site and am working my way through the second book I have found (there are fewer resources as this is an emerging paradigm and a count of published books is often a good indicator of technical maturity and adoption. Note that this reading doesn't make me an expert as I've not applied React in any large scale projects at this time, but it is helpful in assimilating the fundamental ideas behind both technologies.

So far, my take is this:

  1. React wants to be the view and only the view. It excels at separation of concern, hierarchical composition and, possibly most important in a practical sense, high-performance/differential DOM updates.

  2. The Flux architecture says that a combination of action, dispatcher, store and reactive components should guide the development process, where the store is a definitive data state, actions encapsulate mutation events and the dispatcher coordinates action/mutation routing.

The break with traditional MVP and MVVM is largely that model mutations always take place through atomic actions which are dispatched events. It separates the logic from the model (or model view) and simply gates those changes by making them unidirectional (in the everlasting quest to reduce infamous heisenbugs) and part of the update lifecycle.

Assuming I have assimilated these ideas correctly, it seems to me that Knockout observables are very much consistent with the dispatch/store part of this equation and the template model used in Knockout could be replaced with React views without breaking either model.

In fact assuming the Flux dispatcher maps well onto Knockout's pub/sub model, and observables map onto the stores (you would have to manage subscriptions more carefully to avoid paradigm conflicts of course), and, finally, React's views are just another template option for Knockout, I think there is a way to see these as holistic.

I'm still working out a lot of details to find the (conceptual) sweet spot and applying these ideas only in smaller projects to date but, so far, I don't see these two technologies (Knockout and React) as being in opposition. They share a lot of the same concepts (observable stores, pub/sub actions and template/views map fairly well if use properly) and I think the trick is to leverage the strength of each without breaking the architectural principles (which is, as always, a programming choice that is not enforced by either technology).

As a side note, I used D3 with Knockout last year and had to adapt to the idea that D3 does incremental DOM updates and wants to work with differential - in their parlance entry/exit - data. I was able to do this without too much difficulty by hooking into Knockouts update calls and essentially letting D3 do the work that knockout templates usually do. This doesn't seem like either a compromise or a break to either programming model when use to leverage the strength of each. they key, as usually, is understanding.

@kevana
Copy link

kevana commented Dec 18, 2015

Might be relevant for anyone else who finds this from google: https://github.com/lelandrichardson/knockout-react

@bennidi
Copy link

bennidi commented Jul 22, 2016

@claudeduguay I am happy to find someone who elaborated so well on the ideas that came to my mind when starting to use react.js after having played in a few projects with knockout.js. I agree that knockout.js (without the templating) can be seen as the dispatcher/store part of the Flux architecture. The same is true for other functional reactive libraries like rx.js, highland.js... (just to name a few).
I don't exactly know how knockout optimizes DOM updates on changes in observables but I guess it does a fair bit of clever work there (it IS an awesome library). But when you take out that part, what is really left of Knockout? Are the observables that clever and well implemented that they make a good foundation for models bound to react views? Wouldn't observable immutable state be a better choice? immstruct is a very decent examples (unfortunately I found it a bit too late...)

I am writing the foundation for an application with a more complex domain and I although I decided to use react.js (with vanilla coffeescript BTW) I started with building a model layer with all the complex core logic. Testable and with support for validation, i18n, change propagation (EventEmitter) and all. It feels natural for me to start with the model layer (after all the Domain Model is what an application is all about, isn't it?!). Know I am realizing that react components usually arent that well prepared to support this design. They expect to be passed new props / update state instead of being notified of changes. To me that is still something to find good solutions for. I don't want react to take away my model. And a TodoItem is definitely not a React.Class.

Sorry, maybe I went a bit off-topic here. But maybe discussion continues ....

@k-ode
Copy link

k-ode commented Jul 23, 2016

Have you looked into mobx? It's a state manager for react that has borrowed some concepts from knockout. We actually use a custom mobx implemenation with knockout templates and a virtual dom-lib.

@bennidi
Copy link

bennidi commented Jul 23, 2016

@kimgronqvist Thanks for pointing me to mobx. It is EXACTLY what I was looking for.
@mweststrate Thanks for that great piece of work and interview

You guys really made my day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants