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

Passing props in html page #13

Open
artyprog opened this issue Oct 15, 2018 · 3 comments
Open

Passing props in html page #13

artyprog opened this issue Oct 15, 2018 · 3 comments

Comments

@artyprog
Copy link

artyprog commented Oct 15, 2018

Hello,

I confirm that i have the same issue.
If I pass prop (ie name="Bob") in the html page,
this.props is empty ....

I am using Google Chrome on Windows

Regards

@kurtharriger
Copy link

Darn, I was hoping it was just me, it quick look at the source code seems that it extracts props from
appInstance.props = extractAttributes(webComponentInstance);

but if useShadowDom is true it reassigns webComponentInstance to shadowRoot.
// Re-assign the webComponentInstance (this) to the newly created shadowRoot
webComponentInstance = webComponentInstance.createShadowRoot();

So, as a workaround you can disable shadowRoot.
ReactWebComponent.create(, 'my-component', false);

I then ran into the issue that props didn't seem to be set on the first render as it seems the render happens before webComponentConstructed where they get set... so I came up with the following quick hack:

  webComponentConstructed(el) {
  // props is updated parsed by react-web-component just before invoking this method
  // but react doesn't detect this change to props so copy it to state and use state instead.
    this.setState(this.props); 
  }

@kurtharriger
Copy link

After digging deeper I decided to implement the following instead of using this library.
It doesn't have the style stuff and seems to work for me so far but your mileage may vary:

function defineElement(Component, elementName, observedAttributes) {
  class CustomElement extends HTMLElement {
    connectedCallback() {
      const customElement = this;
      const shadowRoot = this.attachShadow({mode: 'open'});
      const props = [...this.attributes].reduce((props, attribute) => ({...props, [attribute.name]: attribute.value }),
        {customElement, shadowRoot});

      const instance =(<Component {...(props)}/>);

      ReactDOM.render(instance, shadowRoot);

      this.instance = instance;
      this.props = props;
    }
    attributeChangedCallback(name, oldValue, newValue) {

      const { shadowRoot, instance, props } = this;
      if(!instance) return;

      const newProps = {...(this.props), ...({[name]: newValue})};
      const newInstance =(<Component {...(newProps)}/>);

      ReactDOM.render(newInstance, shadowRoot);

      this.instance = newInstance;
      this.props = newProps;
    }
  }
  CustomElement.observedAttributes = observedAttributes;

  window.customElements.define(elementName, CustomElement);
}

const HelloWorld = (props) => {
  const onclick = () => {
    props.customElement.dispatchEvent(new CustomEvent('die'));
  }

  return (<h1>{props.greet || "Hi"}, {props.name || "World"}!
    <button onClick={onclick}>Die!</button>
  </h1>);
}

defineElement(HelloWorld, 'hello-world', ['greet', 'name']);

const hello = document.createElement("hello-world");

hello.setAttribute("name", "Visitor");
hello.addEventListener("die",  () => {
  hello.setAttribute("greet", "Goodbye");
});
document.body.appendChild(hello);

@mnemanja
Copy link
Contributor

mnemanja commented Jul 3, 2019

I think this is similar to the issue #7.

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

3 participants