From 818482f6909763aa080a83fce1a2f78bf91a4ecd Mon Sep 17 00:00:00 2001 From: Ivo Pinheiro Date: Wed, 9 Jan 2019 23:26:45 +0000 Subject: [PATCH] Fix #23 - Render canjs component only once on initial load Override can-view-callbacks renderComponent function to when element auto-mount is false the component isn't auto mounted --- can-react-component.js | 9 +++++++++ test/test.js | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/can-react-component.js b/can-react-component.js index 86fa1af..68c014f 100644 --- a/can-react-component.js +++ b/can-react-component.js @@ -3,6 +3,7 @@ var namespace = require("can-namespace"); var assign = require("can-assign"); var reflect = require("can-reflect"); var canSymbol = require("can-symbol"); +var viewCallbacks = require("can-view-callbacks"); var viewModelSymbol = canSymbol.for("can.viewModel"); module.exports = namespace.reactComponent = function canReactComponent(displayName, CanComponent) { @@ -11,6 +12,13 @@ module.exports = namespace.reactComponent = function canReactComponent(displayNa displayName = (CanComponent.shortName || "CanComponent") + "Wrapper"; } + const __renderComponent = viewCallbacks._tags[CanComponent.prototype.tag]; + viewCallbacks._tags[CanComponent.prototype.tag]= function renderComponent(el){ + if(el.getAttribute("auto-mount") !== "false"){ + __renderComponent.apply(this, arguments); + } + }; + function Wrapper() { React.Component.call(this); @@ -47,6 +55,7 @@ module.exports = namespace.reactComponent = function canReactComponent(displayNa render: function() { // eslint-disable-line react/display-name return React.createElement(CanComponent.prototype.tag, { ref: this.createComponent, + "auto-mount": "false" }); } }); diff --git a/test/test.js b/test/test.js index 05f0509..7e16f0f 100644 --- a/test/test.js +++ b/test/test.js @@ -143,4 +143,42 @@ QUnit.module('can-react-component', (moduleHooks) => { }); + + QUnit.test('should be rendered only once', (assert) => { + assert.expect(3); + const ConsumedComponent = canReactComponent( + 'ConsumedComponent', + CanComponent.extend('ConsumedComponent', { + tag: "consumed-component4", + ViewModel: { + first: { + type: 'string', + default: 'Ivo' + }, + last: 'string', + name: { + get() { + return this.first + ' ' + this.last; + } + }, + connectedCallback(el){ + if(el.getAttribute("auto-mount") === "false") { + assert.equal(this.last, "Pinheiro", `'last' name should be 'Pinheiro'`); + } + } + }, + view: stache("
{{name}}
") + }) + ); + + container.innerHTML=""; + + let divComponent = document.querySelector('consumed-component4'); + assert.equal(getTextFromFrag(divComponent), 'Ivo undefined'); + + ReactDOM.render(, container); + divComponent = document.querySelector('consumed-component4'); + assert.equal(getTextFromFrag(divComponent), 'Ivo Pinheiro'); + }); + });