Open Axure opened 6 years ago
@akxcv The problem is this check: https://github.com/akxcv/vuera/blob/d365b07c609ae3cc2fb83e0fd03183c1573dfb11/src/utils/isReactComponent.js#L6-L11
This also happens when using dynamic imports for components:
components: {
MyComponent: () => import(
/* webpackChunkName: 'MyComponent' */
'@/components/MyComponent.vue'
),
}
The problem is, that the function checks for a constructor and its super type, but the component is just a simple factory function, so isReactComponent
returns true...
Edit: I think something like this would work before the lines of code I posted from the original function, but it triggers the promise resolution so there is no benefit in using dynamic imports...
try {
if (component() instanceof Promise) return false
} catch (err) {
console.warn(err);
}
Edit2: Another hack I found that works better than the previous one, as it doesn't resolve the promise:
if (component.toString().indexOf('return __webpack_require__') > -1) return false
Basically it checks if the function returns a dynamic import... Using this hack, this code should avoid unnecessary work:
function isReactComponent(component) {
if ((typeof component === 'undefined' ? 'undefined' : _typeof(component)) === 'object' && !isReactForwardReference(component)) {
return false;
}
let isVue = typeof component === 'function' && component.prototype && component.prototype.constructor.super && component.prototype.constructor.super.isVue
if (isVue) return false
if (component.toString().indexOf('return __webpack_require__') > -1) return false
return true
}
Workaround that prevents writing a fork:
export function markLazyVue<T extends Function>(fn: T): T {
if (!fn.prototype) fn.prototype = {};
if (!fn.prototype.constructor) fn.prototype.constructor = function() { return; };
if (!fn.prototype.constructor.super) fn.prototype.constructor.super = {};
if (!fn.prototype.constructor.super.isVue) fn.prototype.constructor.super.isVue = true;
return fn;
}
Usage:
{
components: {
Tooltip: markLazyVue(() => import("@/components/core/Tooltip.vue"))
}
}
If you use it the
VuePlugin
, and then use asynchronously required components with vue-router, React would complain:Objects are not valid as a React child (found: [object Promise])
.