choojs / choo

:steam_locomotive::train: - sturdy 4kb frontend framework
https://choo.io/
MIT License
6.78k stars 595 forks source link

Create element with own state/context #502

Open jpenna opened 7 years ago

jpenna commented 7 years ago

I am trying to create a TODO app with more than 1 TODO component in the same page, but without using an array.map(...).

I'd like to create the component with it's own state, so I can have one TODO with a list and the other with another list. I am trying something like this:

<div>
  ${todoList(state, emit)}
  ${todoList(state, emit)}
  ${todoList(state, emit)}
</div>

How can I achieve this? When I create it like this they are all sharing the same state. I tried creating a property todoList in state and push the instances there, but I couldn't think of a way to identify what is the first time the element is created and what is a dynamic render event, so I was triggering only the first addState call.

let firstAccess = true;
let thisState;
const componentName = 'todoList';

function initialize(state, emitter) {
  const initialized = addState(componentName, initialState, state);
  firstAccess = false;
  thisState = initialized;
  eventListeners(thisState, emitter);
}

export default (state, emit, emitter) => {
  if (firstAccess) initialize(state, emitter);
[...]

I could use the DOMContentLoaded event, but what if I insert the element dynamically later?

My code is here, if you want to take a look: https://github.com/jpenna/todo_choo


EDIT: Basically, what I want is to initialize the state inside the component (not in the app instance), but when I do this I reset the state.

smcmurray commented 7 years ago

@jpenna

${todolist(state.lists[0], emit)} ${todolist(state.lists[1].emit)} ...

If you don't want them to have the same state, don't pass them the same state.

yoshuawuyts commented 7 years ago

For stateful elements we've begun work on a component abstraction:

Hope comes in useful! (:

jpenna commented 7 years ago

Ok, I will try it! Thank you!