Closed ripter closed 4 years ago
please check https://github.com/WebReflection/augmentor#augmentor as currently I have zero time to fix anything in here. apologies for any inconvenience
I've finally found the culprit of this issue, after a whole refactoring and redesign of augmentor.
This page shows a working example https://github.com/WebReflection/lighterhtml/blob/master/test/aug.html
The reason your example doesn't work, is that you cannot actually have more than a single html
usage per each component, otherwise references go upside down (inside loop first, container after) and everything breaks.
This behavior is well explained in this article too: https://inventingwithmonster.io/20190207-break-the-rules-of-react-hooks/#running-hooks-within-a-loop
I am going to close this, as there's literally nothing to do for me here, just eventually provide better examples of how to use augmentor with lighterhtml.
So are you saying the problem is because there is the nested html
in there?
return html`<ol id="controls">
${ingredients.map((name) => html`<li>
<h1>${Title(name)}</h1>
<h2>Count:
${ingredients.reduce((a, i) => a + (i === name ? 1 : 0), 0)}
</h2>
<div style="display: none;">
<button onclick=${remove(name)}>Remove</button>
</div>
</li>`)}
</ol>`;
If I understand that correctly, each time I want to use html
I have to make it it's own component?
If I understand that correctly, each time I want to use html I have to make it it's own component?
Yes, it's a limitation of the useRef
logic. I might find a better work-around in the future, but right now you need to write your example like this one: https://codepen.io/WebReflection/pen/KKKoOKO?editors=0011
P.S. the easiest way to create and use components and hooks is neverland, which uses dom-augmentor so that useEffect
works as expected out of the box.
P.S.2 another approach is to use some extra feature of lighterhtml
as I've done in here https://codepen.io/WebReflection/pen/wvvmVgZ?editors=0011
The key is in the difference between inner and outer html definition.
const {render, hook, Hole} = lighterhtml;
const {html, svg} = hook(useRef);
const inner = (...args) => new Hole('html', args);
In this way you don't need to use extra components, but you do need to remember to use inner
within the render:
return html`<div>
<button onclick=${() => {
setHistory(history.concat([i]));
}}>${text} ${i}</button></div>
<ul>${history.map(num => inner`<li>${num}</li>`)}</ul>`;
Having one component looks somehow cleaner, but I think I might use this example to improve neverland too.
If interested, the next release should have:
const {render, hook} = lighterhtml;
const {html, svg, inner} = hook(useRef);
and the ability to write the following:
return html`<div>
<button onclick=${() => {
setHistory(history.concat([i]));
}}>${text} ${i}</button></div>
<ul>${history.map(num => inner.html`<li>${num}</li>`)}</ul>`;
So ... inner
exported now, you can see it live here https://codepen.io/WebReflection/pen/wvvmVgZ?editors=0011
Example: https://codepen.io/ripter/pen/LKpbgd?editors=0011
const [history, setHistory] = useState([0]);
withsetHistory(history.concat([i]));
triggers the re-render as expected. The console.logs show the data has been updated; but the html is rendered as if the data were empty.Click the button in the example to see the list disappear instead of rendering the new item. And the button does not update to show the new value of
i
.