React Knockout BindingHandler
by luggage66
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Enter Name: <input data-bind="value: name, valueUpdate: 'afterkeydown'" /> <br />
You Entered:
<div data-bind="react: renderSomeReactComponent"></div>
Babel + JSX
const reactBindingHandler = {
init(element, valueAccessor, allBindings, viewModel, bindingContext) {
// make sure we cleanup, later.
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
ReactDOM.unmountComponentAtNode(element);
});
// and tell knockout to keep it's grubby mitts out of the react-generated DOM
return { controlsDescendantBindings: true };
},
update(element, valueAccessor, allBindings, viewModel, bindingContext) {
const renderFn = ko.unwrap(valueAccessor());
// call the function provided. Assuming the function reads observables,
// they will be observed so that this component updates.
const componentTree = renderFn.call(viewModel);
// (re)render.
ReactDOM.render(componentTree, element);
}
};
ko.bindingHandlers.react = reactBindingHandler;
class MyViewModel {
constructor() {
this.name = ko.observable('Jimbo');
}
// will re-render then observable change.
renderSomeReactComponent() {
return <p>{this.name()}</p>;
}
}
let myViewModel = new MyViewModel();
ko.applyBindings(myViewModel);