DEV Community

Discussion on: How State Management works? Dead simple SM in Vanilla JavaScript

 
artydev profile image
artydev

Hello Matt,
Please ask real questions, read authors posts, share your tips, examples
That will be constructive for all of us
Regards

Thread Thread
 
sgroen profile image
Viridi • Edited

First of all great post Vijay!

artydev is right about the fact that the code could be optimized but Matt is also right. Adding a library does not optimize this piece of code.
Having a look at the code there is only one thing that changes and that is text in the last h1 tag. So if you want to optimize this code why not do it like this?

<!DOCTYPE html>
<html lang="en">
<head>
    <title>State Management in Vanilla JS</title>
</head>
<body>
<h1>Hello Vanilla JS!</h1>
<div>
    Example of state management in Vanilla JS
</div>
<br />
<h1 id="app"></h1>
<button id="button">Increase</button>
<script>
    const App = function _App() {
        return _App.state.count;
    };

    App.state = {
        count: 0,
        increment: () => {
            App.state.count++;
            App.state.updateUI();
        },
        updateUI: () => {
            document.getElementById("app").textContent = App();
        }
    };
    App.state.updateUI();
    document.getElementById("button").addEventListener("click", App.state.increment);
</script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

There is no need to add the event listener on every update and there is no need to rerender the rest of the html on every update. Just update the text in the h1 tag and minimize the rerendering needs. If you want to build the html from javascript you can render the html just once on initialization.

Thread Thread
 
artydev profile image
artydev • Edited

Thank you for your tips
You are totally right if you have
few elements to update.

Regards

Thread Thread
 
sgroen profile image
Viridi • Edited

No problem artydev. You can of course always fall back on a library when you have a lot of re-rendering going on. I believe that to make the right decision you need to understand what is going on under the hood. There are a lot of tutorials on diffing and VDom to be found on the internet for those interested.

Thread Thread
 
vijaypushkin profile image
Vijay Pushkin

Hi there Viridi. Thanks for your input.

But optimising and moving all the elements to HTML wasn't the point of this article

Thread Thread
 
sgroen profile image
Viridi

Hi Vijay Pushkin,

You are absolutely right. artydev and Matt Kimek started a discussion about optimization. I just hooked in to that. Your post was about handling state in vanilla javascript and you did a good job on that.

Thread Thread
 
artydev profile image
artydev • Edited

And only for the pleasure , here is a case when using a library worth it :-)

<div class="my-chrono"></div>
<div class="my-chrono"></div>
<div class="my-chrono"></div>
<div class="my-chrono"></div>
<div class="my-chrono"></div>
<div class="my-chrono"></div>
Enter fullscreen mode Exit fullscreen mode
import {define} from 'wicked-elements';

let Counter = function () {
  let count = 0;  
  let disabled = false;
  let timer;
  let start = () => {timer = setInterval(() => { count += 1; disabled = true; m.redraw()}) };
  let stop = () => {clearInterval(timer); disabled = false; m.redraw()};
  let reset = () => {stop(); count = 0};
  let disable = (status) => status;
  let view = () => [
    m(".wrap", 
      m("h1",  count ), 
        m("",
        m("button", {onclick : start, disabled : disabled}, "start"),
        m("button", {onclick : stop}, "stop"),
        m("button", {onclick : reset}, "reset")
      ) 
    )
  ]
  return  { view }
}

function renderComp(target, component) {
   m.mount(target, component);
}

define(".my-chrono", {
   init() {
     renderComp(this.element, Counter);
   } 
})

Enter fullscreen mode Exit fullscreen mode

You can test it here :

MulipleCounters