0

我想知道为什么下面的代码片段没有更新 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 中。

4

1 回答 1

0

使用hyper.Component最好的方法是使内容有条件,而不是整个根。

为此,您可以简单地使用三元array.concat(...)或任何其他方式来更新组件。

这就像更新实例和替换实例之间的区别。从内部看,组件无权在其父组件上替换自己,除非您明确这样做。

然而,这个例子比看起来要简单,你可以看到它在这个Code Pen上工作。

此外,如果你没有在类中指定onconnectedondisconnected回调,则不需要在节点上指定它们。

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());

我希望这会有所帮助。

于 2017-10-04T17:38:21.063 回答