-
Notifications
You must be signed in to change notification settings - Fork 60
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Taking inspiration from Hooks (i.e., React), a state preserving mechanism like useState(..) is proposed.
You could use it in do-routines like this:
IO.do(component).run({});
function *component(viewContext) {
var [ id, updateID ] = yield useState(() => Math.floor(Math.random() * 1000));
console.log(`random ID: ${id}`);
id = yield updateID(42);
console.log(`fixed ID: ${id}`);
}There are some unresolved issues with such a mechanism:
- The
nextSlotIdxneeds some way to be reset between invocations of thecomponent(..) - State is by default shared among all invocations in the same view-context... perhaps need a more explicit mechanism for forcing a sub-view-context for encapsulating the state
- Since this uses numeric slot indexing (as React/etc does), there's no clear way to share/access state by some unique name. State sharing is an important requirement, so need to figure out to design that into this mechanism. Perhaps an optional ID that overrides using numeric slot indexing.
Here's a candidate first implementation:
function useState(initialVal) {
return IO((viewContext = {}) => {
var { state = {}, } = viewContext;
viewContext.state = state;
var { nextSlotIdx = 0, slots = [], } = viewContext.state;
state.nextSlotIdx = nextSlotIdx;
state.slots = slots;
var curSlotIdx = state.nextSlotIdx++;
if (!(curSlotIdx in slots)) {
if (typeof initialVal == "function") {
initialVal = initialVal();
}
slots[curSlotIdx] = initialVal;
}
return [ slots[curSlotIdx], function update(nextVal){
return IO(({ state: { slots, }, }) => {
if (typeof nextVal == "function") {
nextVal = nextVal(slots[curSlotIdx]);
}
return (slots[curSlotIdx] = nextVal);
});
}];
});
}Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request