DEV Community

artydev
artydev

Posted on

JSX is not your Javascript friend, and do you really need it ?

JSX is certainly and awesome tool, but this as a cost.

  1. It does not allow comments
  2. It does not allow intermix Javascript code.
  3. It must be transpiled with babel
  4. ...

Of course there are alernatives, like 'html' tag templates. But they also suffer some of the JSX problems.

Suppose we have to create a "grid of numbers" component and have to display two components of this type in a legacy app.

Would you use React, Angular, Vue, Solid...?

Here is a solution in plain Javascript.

<script src="https://cdn.jsdelivr.net/gh/artydev/mvu@2.0/dist/mvu.umd.js"></script>

<h2>
  A simple grid with MVU
</h2>

<div id='app'>
</div>

<script>
  const {dom, udom, m, render } = MVU;

  const cellStyle = `
    text-align:center;
    padding-top:10px;
    display:inline-block;
    width:50px;
    height:50px;
    color:white;
    font-weight:bold;
    cursor:pointer`;

  let div = m("div"); // create a div factory
  let br = m("br");   // create  a br factory
  let hr = m("hr");   // create  a hr factory
  let h2 =  m("h2");  // create  a h2 factory

  let selectedCell = div();

  let cell = (i) => div(i, {style: cellStyle});

    function App (numgrid, bgcolor="deeppink") {
    let app = dom();   // here we wrap our grid component between (dom(), udom() <=> <div></div>)    
      for (let i = 0; i < 10; i++) {
        for (let j = 0; j < 10; j++) {
          let content = String(j + 10*i)
          let c = cell(content); 
          c.onclick = () => 
            selectedCell.innerHTML = `<h2>Selected cell : ${content} in grid n° ${numgrid}</h2>`
        }
        br()
      }
    udom();
    app.style= `width:500px;background:${bgcolor};`
    return app
  }


  function main () {
    render(
      document.getElementById("app"), 
      selectedCell,
      App(1,"green"),
      br(),
      App(2, "orange"),
    )
  }

  main()
</script>
Enter fullscreen mode Exit fullscreen mode

You can test it here : Grids

And here is another demo :

const {dom, udom, m, render } = MVU;

let h1 = m("h1")
let button = m("button")

const numCounters = 5

const state = {
  counters : [...Array(numCounters)].map(() => 0)  
}

const Counter = (state, num) => {
  h1(`Counter : ${state.counters[num]}`)
  let incButton = button("inc");
  incButton.onclick = () =>  { state.counters[num]++;  updateApp(state) }
} 

function App (state) {
  let view = dom();
    h1("This is a basic demo");
    [...Array(numCounters)].map((_,index) => Counter(state, index));
  udom();
  return view
}

function updateApp (state) {
    render(app, App(state))
}


updateApp(state)

Enter fullscreen mode Exit fullscreen mode

You can test it here : Counters

Pay attention to this piece of code :

function App (state) {
  let view = dom();
    h1("This is a basic demo");
    [...Array(numCounters)].map((_,index) => Counter(state, index));
  udom();
  return view
}
Enter fullscreen mode Exit fullscreen mode

We can use plain Javascript in our component, comment it, without
any transpilation, isn't that nice ?

Top comments (0)