synacor / preact-i18n

Simple localization for Preact.
BSD 3-Clause "New" or "Revised" License
205 stars 18 forks source link

MarkupText will reapply innerHtml on every parent state change #19

Closed ajarbol closed 4 years ago

ajarbol commented 6 years ago

MarkupText uses dangerouslySetInnerHTML under the hood and due to a known issue in preact any parent component updates will trigger a reapply of dangerouslySetInnerHTML within the child MarkupText.

This will happen even if the MarkupText is not affected directly and can have quite severe performance implications.

A fix has been attempted https://github.com/developit/preact/pull/894, but it's not stable.

In this example MarkupText will update on every mouse move even through the state isn't even used in the render method.

import { h, Component } from 'preact';
import { MarkupText, IntlProvider } from 'preact-i18n';

import definition from './fr.json';

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      mouseY: 0,
      mouseX: 0,
    };
  }
  _onMouseMove(e) {
    this.setState({
      mouseY: e.clientY,
      mouseX: e.clientX,
    });
  }
  render() {
    return (
      <IntlProvider definition={definition}>
        <div className="fullscreen" onMouseMove={this._onMouseMove.bind(this)}>
          <MarkupText id="title" />
        </div>
      </IntlProvider>
    )
  }
};
Hubro commented 5 years ago

This is fixed in Preact X.