-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
snabbdom tutorial #14
Comments
This is very interesting! I don't have time for a throughout read right now :( But I really like your recursive |
Thanks for your notes! I think you"re right about the handler naming. I also probably should add the init method like in Elm (actually i use an init action). |
Using object spread properties is a really nice way to modify object without mutating them. I didn't knew such a thing existed. I'm still very impressed by the elegance of the asynchronously recursive I really like the blog post. I think the examples and explanations are splendid. If I were you I'd go over the post one more time for grammar. I can also add more Medium notes if it is ok with you. Why have you chosen not to use |
I agree, great work @yelouafi ! I like how you build up the concepts from a series of examples. I too am impressed with that My main suggestion would be to split it into chapters (if Medium lets you do that). For instance: I found it a bit hard to follow when you are in some cases adding to previous examples and in other cases starting 'from scratch'; sometimes there is an interlude when you're introducing new concepts, etc. but the breaks are not obvious in one long article. Chapters would let you group the examples in a logical way together with the concepts. Also you could split out the mechanical stuff into its own chapter (npm , browserify, watchify, etc.). And you could add a longer bit about your TodoMVC. That 'simple router' is quite interesting and worth walking through. Also your tests which you touch on, but IMO it's at least worth pointing out just how nice it is to be able to test application state transitions independent of the DOM (independent even of the views) like this. 👍 |
@paldepind thanks again for you notes! i appreciate you help. I'll recheck the post (English grammar isn't my strong point). Please feel free to add any relevant note you see. My main hesitation on adding the 'init' function is that it can be expressed through an 'init' action. i felt that i'd be better keeping number of concepts to the minimum. But i'm not myself convinced 100%, one part of me keep wanting to add an explicit 'init'. Do you think adding an explicit function leads to better understanding than an 'init' action ? @ericgj thank you! glad you liked the post. Medium is quite restrictive when it comes to organizing your content; there is only 3 title styles (h1 for the main title, and h2 and h3 for the rest). the article is split in 2 parts : a snabbdom tutorial and the elm architecture, inside the 2nd i followed the same path as in Elm tutorial. Do you see a better way? i'm open to any suggestion. As for the MVC i felt that the article was already too long. maybe i can add another post on it. An issue i'd like to hear your opinion about is relative to external events. Actually the way 'main' is implemented makes it non trivial on how to integrate external events like triggering an async action or handling out-of-view events like window's events. For example in this example function async(handler) {
handler(Action.RequestStart());
asyncRequest(..., response => handler(Action.RequestEnd() ); // won't necessarily work !
}
function view (model, handler) {
h('button', on: { click: () => async(handler);
} If meantime the view was invoked before the asyncRequest completes (i.e. a user event was triggered between the request's start and end). the handler parameter will become obsolete (the state captured in its closure inside main is no longer valid). actually, i've implemented 2 examples with 2 different solutions the first uses a mutable variable 'currentHandler' that's updated in every view invocation: i don't like this solution but it has the advantage of simplicity the second tries to isolate the currentHandler mutation inside a separate module. and triggers the mutation from the 'patch' function call by using the hooks feature of snabbdom. i used the same solution to connect to the window 'hashchange' events in the todoMVC example. there is still a mutation but it's kept separated from the component. But perhaps there is a better or simpler solution. I'm not sure but i think in Elm async requests are handled by the runtime. |
I can understand your idea. Getting rid of the To see what I mean take a look at this code from your tutorial: function update(count, action) {
return Action.case({
Increment : () => count + 1,
Decrement : () => count - 1,
Init : number => number
}, action);
} There is something very different about the |
@paldepind i see, the 2 operations are different in their purposes, meanings and type signatures. that's more than sufficient to introduce in a separate function. I'll modify the post then. |
I think there is something wrong with the example here. You pass the handler to A similar but slightly different idea. What if we give up the nice sweet looking main function and turn it into something like this imperative thing: let state, vnode, update, view
function main(initState, element, {_view, _update}) {
state = initState
vnode = element
view = _view
update = _update
view(state, handler)
}
function handler(action) {
state = update(state, action)
vnode = patch(vnode, view(state, render))
} The main difference here is that function getAsyncMsg(handler) {
handler({type: ASYNC_START});
setTimeout(() => {
handler({ type: ASYNC_END, data: 'Hello async'});
}, 2000);
} Because the handler is never outdated. I'm not sure if this is a better or worse solution but it does appear to be a solution. And it appears to be quite natural in usage even though the implementation of the main function turns out to be much less elegant. |
I think your solution is the most practical one. The mutation inside 'main' avoids all the other dirty tricks inside components. But there can be an issue if the main handler was wrapped inside a dynamic handler before passed down to a nested component. although the wrapped/main handler is static. If the dynamic handler relies on some data on the model. there is a risk of using an outdated version of that data. |
Yes. That is true. I had not thought about that. I think it can be avoided and worked around in practice but it might still be a source of confusion. |
Is this article done? I'd like to tweet it and include a link to it in the readme of the repository on noname repository. |
Yes. Thanks for sharing. |
@paldepind I just finished writing a post about developing virtual-DOM applications using snabbdom + Elm architecture. the focus is on writing application using pure functions
the url is here
https://medium.com/@yelouafi/react-less-virtual-dom-with-snabbdom-functions-everywhere-53b672cb2fe3
the article is not yet published.i'm interested in any comments regarding adding of modifying something.
The text was updated successfully, but these errors were encountered: