preact-router icon indicating copy to clipboard operation
preact-router copied to clipboard

Router is re-using DOM elements, how could I force a new one?

Open mattdesl opened this issue 8 years ago • 2 comments
trafficstars

Hi there — in our code we tend to apply CSS to a component on componentDidMount (specifically, using GSAP for complex animations).

However, when routing around I've noticed that preact-router (or preact itself?) likes to hold onto DOM nodes where possible, rather than creating a new one. This mutability forces us to write code that always resets the CSS state of a component on mount.

Here is an example; where the style is set on mount, and when re-routing to that component the style will already have been set from the previous route change.

Or am I misunderstanding the way preact/vdom works? Is there a way to force the re-creation of a DOM element so I can mutate its styles/etc without concern for how it will break future mounting?

import Router, { Link } from 'preact-router';
import { h, render, Component } from 'preact';

class TestComponent extends Component {

  componentDidMount () {
    if (this.base.style.padding) {
      console.error('Padding is already set...', this.base.style.padding);
    }
    this.base.style.padding = '20px';
  }

  render () {
    return <div />
  }
}

class About extends Component {

  render () {
    return <div>About</div>
  }
}

class App extends Component {
  
  render () {
    return <div>
      <Link href="/">TestComponent</Link>..
      <Link href="/about">About</Link>
      <Router>
        <TestComponent path="/" default />
        <About path="/about" />
      </Router>
    </div>
  }
}

render(<App />, document.body);

mattdesl avatar May 11 '17 19:05 mattdesl

Hi there - if you add unique key properties to the children of router, it will always unmount and mount:

class App extends Component {
  
  render () {
    return <div>
      <Link href="/">TestComponent</Link>..
      <Link href="/about">About</Link>
      <Router>
        <TestComponent key="test" path="/" default />
        <About key="about" path="/about" />
      </Router>
    </div>
  }
}

developit avatar May 16 '17 15:05 developit

same here

Kiarash-Z avatar Jul 17 '18 15:07 Kiarash-Z