logo

Example: Components consuming State

Additionally to receive arguments (which are more or less constant), a component can also consume different dynamic state variables as arguments.
That empowers you to pass state from component to component in whatever fashion you want.
You can f.e. pass a different state to equal components or the same state to different components anywhere in the DOM (which is not possible in many other frameworks).

1. Start with the usual index.html-file where you define a div-Tag with an id of your choice.

    
<!-- index.html -->
<div id='myapp'></div>
<script type='module' src='app.js'></script>
    
    

2. In app.js, we set up our project as usual.
We import the components Feeder, Dog, Cat and a Wrapper called AnimalFarm.
Notice that the dog named Max is only listening to food while Milo and the cat Misty are listening to both state variables food and extraFood.

    
// app.js
import { RobJSApp } from './Rob.js'
import { AnimalFarm } from './AnimalFarm.js'
import { Cat } from './Cat.js'
import { Dog } from './Dog.js'
import { Feeder } from './Feeder.js'

const app = new RobJSApp('myapp')
app.init('app')

app.defineStateVar('food', 0)
app.defineStateVar('extraFood', 0)

app.registerComponent(Feeder, 'feeder1', ['food', 'extraFood'])
app.registerComponent(Dog, 'dog1', ['food'], 'Max')
app.registerComponent(Dog, 'dog2', ['food', 'extraFood'], 'Milo')
app.registerComponent(Cat, 'cat1', ['food', 'extraFood'], 'Misty')

app.initialRender(AnimalFarm)
    
    

3. In our components we need to define our state variables as parameters after the constant parameters.
Also keep the same order as you registered the state variables in the registerComponent-function state variables array.

    
// Dog.js
export const Dog = (id, name, food, extraFood) => {

  if(!extraFood){
    extraFood = 0
  }

  return `
      <div id=${id}>
          <p>Dog: ${name}</p>
          <p>Food received: ${food + extraFood}</p>
      </div>
  `
};

// Cat.js
export const Cat = (id, name, food, extraFood) => {
  return `
      <div id=${id}>
          <p>Cat: ${name}</p>
          <p>Food received: ${food + extraFood}</p>
      </div>
  `
};

// Feeder.js
export const Feeder = (id) => {
  return `
      <div id=${id}>
          <button onclick='app.updateState("food", app.state.food + 1)'>Give food (${app.state.food})</button>
          <button onclick='app.updateState("extraFood", app.state.extraFood + 1)'>Give extra food (${app.state.extraFood})</button>
      </div>
  `
};

// AnimalFarm.js
import { Cat } from './Cat.js'
import { Dog } from './Dog.js'
import { Feeder } from './Feeder.js'

export const AnimalFarm = () => {
    return `
        <div>
          ${Feeder('feeder1')}
          ${Dog('dog1')}
          ${Dog('dog2')}
          ${Cat('cat1')}
        </div>
    `
};
    
    

4. With a bit of styling it looks and works like this.

© - RobJS.org - All rights reserved