Code Monkey home page Code Monkey logo

Comments (6)

smalluban avatar smalluban commented on May 14, 2024 1

It is a very interesting case :) How to start... Hybrids uses prototype mechanism to define properties, and they are getter/settter properties. In JavaScript when you set the value to those properties, instead of creating own property (on the top object instance), the set method from the prototype is called. It means that the instance still does not have own property... Now, let's see your code. In your example you are passing host properties into the React component using spread operator - by the definition, it only passes "own" properties, so it should not work at all. However, why does it work in Angular? It should not work too, but if it really works it means that angular has a problem and not use the prototype (proper assertion, using '=' operator), but set property by Object.defineProperty() method and does it on the instance (which would stupid by the way).

The second problem of your WC generator is that you don't define input properties - so hybrids will not re-render your component when they will change... Hm.. It might be a answer why it works in angular, but not in Vue - they might pass properties at a different moment in time - the first before appending to the DOM, and the latter after. Hybrids renders your template for the first time with (Angular) or without (Vue) properly set properties.

How you can fix it? Your React components should inform what kind of input properties they use. If you don't care about types, you can define them all with undefined value in hybrids component definition, but you have to do this. Then, if you will have a list of input properties, you should explicitly pass them to React component rather than using the spread operator. I think static propTypes can help you with that.

// Grab all of the momentum-ui react components
const webComponents = Object.keys(Components).reduce((acc, key) => {
  // Grab the react component whenever being invoked 
  const Component = Components[key];
  const inputProps = Object.keys(Component.propTypes);

  const component = {
    render: render(() => {
        return (host, target) => {
          const props = inputProps.reduce((acc, key) => {
            acc[key] = host[key];
            return acc;
          });
          // Render the component with the given properties
          ReactDOM.render(<Component {...props} />, target);
        }
    },  { shadowRoot: false }) // No to Shadow DOM
  };
    
  // Define input props of the React component
  inputProps.forEach((key) => {
      component[key] = undefined;
  });

  // Convert the PascalCase string with lowercase string plus dashes in between
  const name = `web-comp${key.replace(/[A-Z]/g, m => "-" + m.toLowerCase())}`;
  acc[name] = component;

  return acc;
});

define(webComponents);

from hybrids.

akoushke avatar akoushke commented on May 14, 2024 1

@smalluban will do. Some react components from that third party library are missing prop-types. Iā€™m trying to figure out why, but I was planning to just make this work with the other components. Will update you ASAP.

from hybrids.

smalluban avatar smalluban commented on May 14, 2024 1

I'm assuming using reactDom.render many many times is not the best approach for a large scale application.

If you plan to build "a large scale application" and use a lot of react components, it might not be the best idea to wrap them all in web components ;) The main goal of wrapping React in web components is to let users from other frameworks use particular components with a standardized way without need to use React directly.

However, I always thought that calling ReactDOM.render after initial load will work the same as you would call forceUpdate() inside of the component. As we know, that props have changed (because of how hybrids cache works) it is the same as passing new props to the component inside of the React tree. It should not have a performance impact on your application.

There is an issue in React repo about it, which is signed as a bug, and what I read it's solved: facebook/react#12700

from hybrids.

smalluban avatar smalluban commented on May 14, 2024

@akoushke Let me know if my solution works. If you don't have any other problem with the case please close the issue.

from hybrids.

akoushke avatar akoushke commented on May 14, 2024

I'm going to close this right now. Will update you if there was any more issues. thanks again.

from hybrids.

akoushke avatar akoushke commented on May 14, 2024

I did have another question in terms of using reactDom.render.
I'm assuming using reactDom.render many many times is not a best approach for a large scale application. However, I found that's the only way to wrap a react component into a web component.
Obviously I'm talking about this line of code here:

ReactDOM.render(<Component {...props} />, target);

Is there a way to come up with a precompiled html code without given properties? maybe I can use that html template into my web component definition and embed the props later in the runtime? That way I don't have to call ReactDom.render for each component. I just return the html code with given embedded properties. does this makes sense? I know that ReactDomServer offers html initial from a given react component. However, you will need to pass a react element first which requires props and/or children. any suggestions? I'm all ears!!!! thanks <3

from hybrids.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.