Условный рендеринг в гипер. Компонент, не обновляющий DOM

Интересно, почему следующий фрагмент не обновляет DOM?

    const { hyper, wire } = hyperHTML;

    class Input extends hyper.Component {
      get defaultState() {
        return { error: false };
      }
      onclick() {
        this.setState(prev => ({ error: !prev.error }));
      }

      render() {

        const textField = wire()
        `
          <div onconnected=${this} ondisconnected=${this}>
            <input type="text" value="foo" onclick=${this}>
            <label>bar</label>
          </div>
          `;


        let finalNode;
        if (this.state.error) {

          finalNode = this.html `
            <div>
              ${textField}
              <p>
                some name
              </p>
            </div>
            `;

        } else {
          finalNode = this.html `
            <div>
              ${textField}
            </div>
            `;
        }
        return finalNode;
      }
    }


    document
      .getElementById('root')
      .appendChild(new Input().render());

Я ожидал бы, что он будет сначала визуализировать textField, а по щелчку - p элемент. Я вижу, что вызов рендеринга сделан, но результирующий элемент не попадает в DOM.

1 ответ

Решение

С hyper.Component лучший способ сделать контент условным, а не корневой в целом.

Чтобы сделать это, вы можете просто использовать троичный или array.concat(...) или любым другим способом, который обновит компонент.

Это как разница между обновлением экземпляра и его заменой. Изнутри компонент не может заменить себя на своем родителе, если вы явно не сделаете этого.

Однако этот пример проще, чем кажется, и вы можете видеть, что он работает с этим Code Pen.

Более того, если вы не укажете onconnected а также ondisconnected Обратные вызовы в классе, нет необходимости указывать их на узле.

const { hyper, wire } = hyperHTML;

class Input extends hyper.Component {

  get defaultState() { return { error: false }; }

  onclick() {
    this.setState(prev => ({ error: !prev.error }));
  }

  render() { return this.html`
    <div>
      <div>
        <input type="text" value="foo" onclick=${this}>
        <label>bar</label>
      </div>
      ${this.state.error ?
        wire(this, ':extra')
        `<p> some name </p>` :
        null
      }
    </div>`;
  }
}

document.body.appendChild(new Input().render());

Я надеюсь, что это помогло.

Другие вопросы по тегам