Preact: Attach arbitrary dom elements

Created on 15 Mar 2016  路  9Comments  路  Source: preactjs/preact

Hi,
Is there a supported way of attaching arbitrary dom elements in components? Tried using this.base.appendChild but it seems to cause a mess with the caching of components/elements.

In my case I want to use a datepicker that has nothing to do with preact or react wrapping it in a component for easy use.

Any help appreciated
Thanks

documentation question

All 9 comments

@kruczy The best way to do this is to append the element to this.base, but you will need to disable component rendering in order to keep that element from being reclaimed (see example below).

You can see this technique in action in preact-token-input - it uses a component as a foothold in the DOM, but then disables updates and lets tags-input take over from there. A more complex example would be preact-richtextarea, which uses this technique to avoid re-rendering an editable <iframe>.

class DatePicker extends Component {
  shouldComponentUpdate() {
    // do not re-render via diff:
    return false;
  }

  componentWillReceiveProps(nextProps) {
    // you can do something with incoming props here if you need
  }

  componentDidMount() {
    // here's where you can inject the external date picker element:
    let datePicker = document.createElement('input');
    datePicker.type = 'date';
    this.base.appendChild(datePicker);
  }

  render() {
    return <div class="date-picker" />;
  }
}

@developit thanks for this! that is very helpful, will try this in a sec

@kruczy You're quick! I just threw together a demo of this on Webpackbin:
http://www.webpackbin.com/V1hyNQbpe

I wanted to make sure I wasn't crazy (haha) - the demo shows that even when re-rendering from a parent component (<Example>), the <DatePicker>'s DOM is preserved.

Cheers! :)

well @developit you're the most responsive and helpful maintainer I came across :+1: and I mean it!

Just did what you suggested and it works perfectly!

Will throw in a componentDidUnmount to cleanup after as well

Thanks alot

Awesome, and thank you!

I added this to the Wiki as documentation for others who might have the same question:
https://github.com/developit/preact/wiki/External-DOM-Mutations

Turns out there is a problem with componentDidMount in a reuse scenario

Made a quick example based on yours with a toggle button and cleanup like in my use case

componentDidMount is called every second time the component is mounted and it should be called every time

see: http://www.webpackbin.com/E1j567bal

Eek! That looks like a caching bug then. Should we open a new issue or use this one?

sure, will do that in a sec

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthewmueller picture matthewmueller  路  3Comments

jasongerbes picture jasongerbes  路  3Comments

paulkatich picture paulkatich  路  3Comments

rajaraodv picture rajaraodv  路  3Comments

k15a picture k15a  路  3Comments