Условный рендеринг в гипер. Компонент, не обновляющий 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());
Я надеюсь, что это помогло.