HyperHTML - 是否可以更新组件状态而无需重新呈现整个组件DOM?

时间:2017-12-20 13:58:31

标签: javascript hyperhtml

我有以下hyperHTML组件,一切都按预期工作,唯一的问题是每个this.setState()调用都会重新呈现整个组件DOM。

我的问题:

有没有办法在不重新呈现整个组件DOM的情况下更新DOM上的通知字符串?

const { hyper } = hyperHTML;

class searchComponent extends hyper.Component {
    constructor(data) {
        super();
        this.setState({ notification: '' });
    }
    onChange() {
        // ...
        if ( condition ) {
            this.setState(() => ({ notification: 'notification text!' }));
        }
        // ...
    }
    async listTags() {
        //...
        // async content 
        //...
    }
    render() {
        this.html `
        <div id="search_container">
            <select name="tags" id="tags_search" class='form-control m0' multiple="multiple" onChange=${this.onChange}>
            ${{
                any: this.listTags(),
                placeholder: 'incoming..!',
            }}
            </select>
            <div class="search_notification">
                <!-- I want to re render only this part of the DOM -->
                ${this.state.notification}
            </div>
        </div>
        `
    }
}

1 个答案:

答案 0 :(得分:2)

您的代码中很少有陷阱。 首先,onChange将无法按预期工作,您将失去上下文。您只需使用onchange HTML事件,然后调用方法onchange,只使用this作为事件监听器:

const { hyper } = hyperHTML;

class SearchComponent extends hyper.Component {
  onchange() {
    this instaneof SearchComponent; // true
  }
  render() { return this.html`
    <div id="search_container">
      <select onchange=${this}>
      ${...}
      </select>
    </div>`
  }
}

或者在构造函数中绑定onChange方法。

你也忘了在return this.htmlrender(),如果你想把你的组件放在DOM上,这是必需的。

但是,假设这些是无关的错误,为了快速演示代码,你需要了解异步世界是异步的。

如果你有一个异步操作,你无法判断它是否已经解决,你只需要传递它,这正是你正在做的。

您正在更改组件的状态,期望以前不会再次触发异步操作。

但是,组件如何知道这种状态变化是否会产生不同的布局? TL; DR 答案是它不能,稍长一点就是你有一个异步的,不相关的行为,附加到每个更新但是你想要只触发一次异步行为,而不是每次更新。

可能的解决方案

您可以创建子组件作为一个部件,并在SearchComponent初始化期间(constructor)实例化一次,或者只使用比当前更有意义的占位符。

实际上,现在您正在创建类似<select>incoming..!</select>的输出,这与标准HTML无关。

select可以有option个标签,将其用作某些文字的通用容器就像滥用其潜力一样。

您想要的是disabled=${this.optionsResolved}上的select${this.options}内容的数组。

通过这种方式,您在解决选项时无需进行任何更改,并且一旦发生这些选项,就会有适当的选项列表。

您可以在此Code Pen

中查看示例