Hacker News new | past | comments | ask | show | jobs | submit login
Build Your Own React (pomb.us)
1478 points by pomber 23 days ago | hide | past | web | favorite | 108 comments



Very, very nice.

His presentation library is available as well!

https://codesurfer.pomb.us/

https://github.com/pomber/code-surfer/blob/code-surfer-v2/re...


I love this effect, I was actually just writing a blog post that I didn't save before my tab crashed. I'm actually now GLAD it didn't!

This is a lot more effective a medium for the content!

I even went ahead an set up a monthly donation to their open collective project [1] because it is so beautiful.

1: https://opencollective.com/code-surfer


hey, thanks a lot for the donation!


No problem, the tutorial was great and the code-surfer package looks great. Keep up the good work!


Please don't perpetuate this type of animated presentation style. Why?

1) Vertical layout is easier to scroll

2) Vertical layout puts the code blocks in-line to know where they belong in the text

3) Author's presentation style has animations that slow down user's ability to scan quickly

4) Scroll position determines the code block's visibility (!!! WTF)

5) Either have the entire page white or black. The contrast changes between reading the document and then reading the code tires the user

6) Scroll wheel feels highjacked because the left pane is static

I could go on and on. I strongly discourage people from using this type of documentation. Your users, will get tired of the novelty and when push comes to shove, they will want something like this:

https://golang.org/pkg/


Boo - this is clearly excellent work by someone with both engineering and design skills. If no-one pushes the envelope then what a sad and boring world we would end up in.


It’s the best presentation for this style of content that I’ve ever seen. Having a description of what’s going on with a particular code block, plus highlighting the relevant parts, and moving that highlight or swapping out specific parts of it as I go through the content made it much faster for me to grasp what was important and what changed between blocks than would have been the case if the author used traditional static sections of code. This isn’t documentation, it’s a follow-along tutorial, and for that purpose this presentation style is 100% appropriate.


I think static documentation (your link) is a different use case than an interactive tutorial (not documentation). I didn't find the presentation horrible, but it's likely just looking nice and perfect on my computer hooked up to big monitors, and not on a phone or something....


I think everyone is saying that but presentation or documentation is essentially presenting sequential information to the user, whether it is a word document, a slide deck or a scrolling html page.

Also, there is nothing interactive about it - I can't change code on the left side, nor can I do anything with the right side. It is just scrolling, I guess you can call that "interaction".


You're dismissing scrolling as if it doesn't do anything but when I scroll I can see the code at a point in time as opposed to a point in space.


That’s precisely the problem - if both sides were moving together, in time it would be a slide deck, in space it would be a scrolling document. Here, we have the left and right side, changing in time and space, respectively, and burdening the user with cognitive dissonance.


if both sides were moving together, in time it would be a slide deck, in space it would be a scrolling document

There is a fundamental difference between reference material, where only the final version is relevant, and tutorial material, where the evolution is also important. You keep making similar comments in this discussion where you compare this tutorial/exposition format to typical reference documentation, but they're solving different problems and reasonable assumptions in one case don't necessarily hold in the other.

In particular, presenting this sort of tutorial/exposition material as you suggest could make the document much longer, but worse, the reader would have to keep looking at almost the same code snippet and figuring out what changed at each step instead of having it demonstrated by the animation effect. That is a significant mental overhead, and it's a recurring pain point when teaching programming subjects that can be remedied by using something that actively shows the progression. I've used similar techniques where some example code evolves with simple animations in both presentations and private documentation, and it generally seems to be effective at communicating the intended ideas and well received by the target audience.


Exactly. This presentation style made it much easier for me to see what was being added to the code. I don't like having to continually scan different blocks of code to see what changed, and try to make sense of how the changes fit in the bigger picture.


I don't like having to continually scan different blocks of code to see what changed, and try to make sense of how the changes fit in the bigger picture.

Indeed.

Visual diff tools were invented for a reason, and using a side-by-side layout with some sort of colour coding and some attempt to align equivalent code is now close to universal. No-one would suggest doing code reviews by printing out the last two versions of a source file and comparing them on paper any more.

In presenting tutorial material like this, IME the two most effective formats have been either something like that side-by-side diff, often with some extra annotations like chunky labelled arrows to highlight the specific areas or changes of interest, or something like the style here, with the changes at each step being highlighted and/or animated so it's easy to follow along. Both of these work for code but also other illustrations.


I do agree with you. I found it amazing to look at, but not very usable if you just wanna look at the code.

documentation =/= presentation


I love it...


Yeah the presentation effect on code is super cool. Yet on mobile I didn't feel that it was particularly helpful as it covered about half the screen height and I couldn't clearly skim the content.


This might even become standard for most documentations.


> This might even become standard for most documentations.

I hope not, because slow, meaningless animation makes me tired and something inside me wants escape that page. Also it affects scrolling, especially noticeable when I am scanning a text instead of reading - you might lose context (note how the presentation reacts on pressing "page-up" / "page-down"). Kindle and all e-reader hates animations[0][1] - any animations (they are just huge black holes for battery). IMHO any documentation SHOULD be able to printed out on paper and sorry - paper is not interactive.

However, I will warmly welcome some interaction in dedicated docs section but it would be great if it could be duplicated as a rich-text article.

[0]: Not saying about the reader mode in browsers (e.g. Firefox)

[1]: Please think also about people that are disabled or use VoiceOver/NarratorMode to be more productive / are just lazy to read text using their eyes :)


No worries, i understand, but I felt it told the code History in a valuable way. I usually stay away from shiny presentation.


I found it very slick and cool-looking but not really conducive to absorbing information.


I couldn't disagree more. This is not what a documentation should be like.

Unnecessary animations, fixed scrolling, and just useless "snazzy" aspects of user interface has no place in code documentation.

I hope this does not become the standard.


It's a good thing the post is a teaching tool and not documentation!


I don't think it would work well for documentation where you may only look for a very specific piece of information and maybe a little bit context. This style of presentation would, in my opinion, work best for tutorials where every new concept builds on top of previous ones, and context is king.


Is it just me or on mobile it does not render properly?


This is basically unusable in mobile ... but looks nice in desktop though ...


Presentation is amazing here.

That said, I recently wrote a webcomponent based router and I was surprised at how easy it was to get to a very usable point at such a minimal amount of code. All too often I get in the loop of just `npm i`'ing whatever it is I need, even if the functionality I really need is just a tiny subset of whatever huge library I'm importing.

Rodrigo's right that something like this helps you understand React and how to contribute to the codebase, but I think it goes further than that - it lets you understand that the library isn't magic. It gives you the confidence you need to think that maybe you don't need that full 560kb library.


Redux is a very good example of this. If you watch the original talk or just understand primitives like Observables, you can realize that Redux almost isn't a library. It's basically a pattern. Where libraries are actually required is when you connect Redux to React, or need async actions. But even then it's not super hard to see how they work.


Yep. The Redux core `createStore` function can be distilled down to about 25 lines [0], and the rest of the core lib can be added in another 75-ish [1].

I've seen Redux described as "a pattern with really good documentation", and there's some truth to that. On the other hand, we've put a _lot_ of work into React-Redux in particular [2] to make sure it's optimized and works well with React.

As a side note, we have a new official Redux Toolkit package [3] that is our recommended approach for writing Redux logic. It includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.

[0] https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...

[1] https://gist.github.com/gaearon/ffd88b0e4f00b22c3159

[2] https://blog.isquaredsoftware.com/2018/11/react-redux-histor...

[3] https://redux-toolkit.js.org


> webcomponent based router

Routers can be (and should be, IMO) written to be independent of UI component libraries such as React and webcomponents. See an example here: https://github.com/Rajeev-K/mvc-router You can use it with React---and in some ways it works better than react-router.


Yeah I'm not a fan at all of react-router because it's too dependent on React. For redirecting, for example, they recommend you render a <Redirect> component. Which is just bananas to me.


It's not really bananas when you actually start to think of everything 'as components', and consider that 'render' can neatly, declaratively describe behaviour, not just the DOM.


That _is_ how I think about components, but it's still bananas. Render does not neatly describe this behavior because it necessitates setting unnecessary state. That's gross.

Usually when I need to trigger a redirect, I'm in some business-level function. So to redirect this way, I would need to set some state in my store, re-render, then hit the conditional, which would redirect, probably unset that state, and then probably trigger some additional business logic.

When really all I want to do is in the business function, directly trigger the redirect and maybe some other logic without any indirection. redux-react-router exists, but it's API is still obtuse compared to something like redux-first-router.


Then you can use `useHistory` (or `withRouter` if you're not hooks-ready).

I somewhat agree that the <Redirect /> component is not actually that useful, it's only useful in very simple cases like "based on one route plus conditional redirect to another", e.g.:

    <Route path="/">
      {usersPreviousShoppingGender === "women" ? (
        <Redirect to="/women" />
      ) : (
        ...
      )}
      ...
    </Route>
    <Route path="/women">

Since you are talking about using Redux, you most definitely can dispatch push actions with libs like connected-react-router or just use the history API directly (for things like replacing state instead of pushing). Most of the redirects I write are inside business logic and I don't like mixing <Redirect /> in there, too.


> When really all I want to do is in the business function, directly trigger the redirect and maybe some other logic without any indirection.

Heh, didn't see this comment before I left a novel up the tree. Seems we have similar ideas about state management.

I think the default RR API is straight React, and that is by design.


'render' should render, because that's what the function name says. If you're using it for behavior then you're not using it for the intended purpose.


Now that hooks exist, this should definitely be the case. Before, HoCs / components with render prop functions were actually useful for doing some additional not-directly-render related work.


You can now use hooks for some things you might previously want a component for, e.g. useFetch instead of <Fetch />, but don't agree "this should definitely be the case". Dogma is never good.


Strongly disagree, and 'because the function is called that' is a very poor reason.

You're not using React to its full potential if you think like this.


could you recommend any articles/tutorials that describe this approach some more?


This Ryan Florence talk is a great talk that touches on this topic, especially in some of the more creative examples: https://www.youtube.com/watch?v=kp-NOggyz54


thanks!


The alternative would be to write a side effect inside your `render()` function, which is illegal -- it breaks the new Concurrent mode rendering, which can call render() speculatively.

I mean, I see why it's intuitively unappealing to you, but there are perfectly good reasons for the design.


There are "perfectly good reasons" in the sense that if you artificially limit yourself to using the React component tree to manage routes, yes it makes sense how they arrived at this solution. But after dealing with it for a while, it's just so obviously not the correct approach, and it's crazy to me that it's the defacto router. Cargo culting at its finest. The router could exist outside of or at a higher level than the component tree.


It's the defacto router because it has gone through many iterations, has lots of users, is easy to bring into a React app, and doesn't fight w/ React, it works with it. Plus there are a variety of approaches to declaring routes. [0]

I'm not sure I see how obvious it is that a <Redirect/> is wrong. But that's fine, I take your point that it's not particularly intuitive.

I'm of the opinion that routing, in general, is a function of application state - and I like to manage my application state with Redux - so I will often also mix in connected-react-router [1]. This lets you do navigation w/ an imperative API [2].

[0] https://github.com/ReactTraining/react-router/tree/master/pa...

[1] https://github.com/supasate/connected-react-router

[2] https://github.com/supasate/connected-react-router/blob/mast...


The alternative would be to write a side effect inside your `render()` function, which is illegal

That's one alternative. Another is not to try implementing behaviour that has nothing to do with rendering using a rendering library in the first place.

A horrible amount of accidental complexity has been created in the React ecosystem when people have tried to use it like a full framework. If all you have is a hammer, maybe it's time to consider using other tools as well.


It’s bananas to you that a library with the word react in the name would be dependent on react? It’s an add on you would literally never use unless you are building a react app


My favorite routers to use with React at the moment are redux-first-router (define a route map, and an object in your Redux store gets automatically two-way synced with browser location state; your 'routing' is actually just a switch statement over the current location state), and Next.js (make some component files under pages/ and they get automatically rendered as routes; wrap a filename in brackets and it's used as a query param value wildcard). Both have advantages and disadvantages but are very low-mental-overhead in practice.


Disagree there's anything really low-mental-overhead about bringing redux into your project.


Can second redux-first-router being fantastic.


Web components are not a UI library though. They are the native component model for the web.


HTML custom elements (basis for web components) are intended for things that should be added to DOM. Using it for any other purpose is probably a misuse.


In my personal case I'm using it so the DOM is more literal as to what's happening on the page. I'm of the naive opinion that you should be able to read the DOM and have a general sense of what the site looks like. Since I'm making a single-page site that loads everything at once, I have a webcomponent based router that declaratively states what route will be active given the URL. For example:

    𝚖𝚢-𝚛𝚘𝚞𝚝𝚎𝚛
      𝚖𝚢-𝚛𝚘𝚞𝚝𝚎(𝚙𝚊𝚝𝚝𝚎𝚛𝚗="/𝚑𝚘𝚖𝚎")
        // 𝚜𝚘𝚖𝚎 𝚑𝚘𝚖𝚎 𝚙𝚊𝚐𝚎
      𝚖𝚢-𝚛𝚘𝚞𝚝𝚎(𝚙𝚊𝚝𝚝𝚎𝚛𝚗="/𝚗𝚎𝚠𝚜")
        // 𝚜𝚘𝚖𝚎 𝚗𝚎𝚠𝚜 𝚙𝚊𝚐𝚎


not sure what happened, but your code example is almost all tofu (unicode [X]) to me. looks like it's using characters like "mathematical monospace lowercase letter 'm'" etc

edit: unidecoded:

  my-router
        my-route(pattern="/home")
        // some home page
        my-route(pattern="/news")
        // some news page


Especially when you consider a non-trivial amount of the react-dom codebase is actually Synthetic Event handling (smoothing out differences in browser implementations). If you're using "the platform" and understand native events, that's a huge saving for you and your users.


> you don't need that full 560kb library

In fact, most web applications only need this 200-line library: https://github.com/wisercoder/uibuilder

React started out as a simple library, but it is getting more and more complicated (see concurrent mode). 90% of applications don't benefit from React's complexity. This tiny lib has the same templating technology as React, but none of the complexity.


Concurrent mode seems to come out of actual research regarding managing what is rendered when and what people like / don't like and expect to be rendered and when ... and providing more control over that.

I guess that's complicated but I can see even basic apps benefiting from it.


Forget building my own React, I want to build how you did the presentation! It’s a great concept!


Here's the Gatsby theme https://www.gatsbyjs.org/packages/gatsby-theme-waves/ (and on GitHub https://github.com/pomber/gatsby-waves)

Great article and awesome storytelling there!


I agree, though, it's a shame there's no fallback for when there's no javascript.


[flagged]


It’s a legitimate comment. You should be able to browse and view readable text without js enabled, whether or not the contents of that text discuss JavaScript.


Along a similar vein, Sophie Alpert did a talk[1] at React Conf this year on building your own React custom renderer by using implementing the interfaces that React exposes. Sophie explains how you could use React as a declarative API for pretty much any platform if you wanted, similar to how react-native works.

[1] https://www.youtube.com/watch?v=CGpMlWVcHok


Which is actually a little funny, because that's essentially turning React into a domain specific language for UI rendering. The Racket people are probably facepalming that we had to go via JavaScript and Babel to get to a UI DSL.


If Racket had a declarative UI DSL, I'd be using that, but they don't.


It is exactly that, a small library for ui, written in ocaml, ported to a scripting language with immense amount of work, and years and years of educating people with white lies :)


I think that inverting the order, putting the text on the left and code on the right would work much better.

For me, it felt quite unnatural to go against the normal reading direction. I believe that because we read left-to-right, and the additional content is usually on the right, it would be easier for the eyes to search for the examples on the right rather than backward. It felt very distracting.

Great content though!


I really like the UI of this blog. On mobile it's a bit annoying to have the top half of the screen be filled by a black block of code, but on desktop it look definitely awesome.


The presentation is stellar! I love the animated code changes on the side <3



Very nice. This guy is going places.

Hey Rodrigo so how performant do you think this didactic example would be compared to React? Maybe 80% there?


Much less than 80%. Half of React code is optimizations, and not only speed, for a medium sized app I guess React uses less than 20% of the memory that Didact uses.


This is great. I did the same for Express.js last year. If anyone interested in it, here is the link: https://github.com/antsmartian/lets-build-express


What a great tutorial!

I wanted a React-like TUI lib for a Clojure project and ended up writing facsimile by looking at the React source. Reading the React source to try to understand how React works is very challenging. This would have made the perfect guide. Thank you.


Wasn't there a very similar article recently? Wouldn't mind if this is a new tutorial trend. Regardless the presentation of this article is great! I hope this also catches on, it has maximum scanning efficiency.


What’s the trend here?


I find that these kinds of tutorials are great at all stages of my experience.

As a beginner, it's helpful to watch someone's thought process as they build something from scratch. I remember not even knowing where to start.

As a more experienced developer, I tend to know how things work independently, but am always interested to see how you might go about stitching them together at a high level.

Here, I liked the concurrent-mode and fiber patterns broken down into their simplest implementation to get the point across.


I think concurrent mode and fibers are kludgy hacks that arise from the problem that only the main thread has access to the DOM. As far as I know and I may be ignorant but few, if any, other frameworks are scheduling DOM updates as aggressively as React is, and are simpler to understand as a result.

Hopefully the standards folks can come up with a decent DOM API for WebAssembly.


This is a great way to understand code. Why write comments, when you can make presentations? Are there similar tools like this?


Reminds me of the book "Build Your Own AngularJS" from a couple of years ago. - https://teropa.info/build-your-own-angular/

Old now, but still worth reading IMHO as you learn a lot.


Is this the same concepts behind Vue as well? As someone that hasn't yet dabbled in the 'new' frameworks I love how this bridges the gap of understanding. Thank You!


This is great.

Implementing core libraries/frameworks you use day-to-day, from scratch / for fun, is one of the best and most practical ways to level up as a dev.


WOAH amazing presentation, this is how code should be explained.

Quick validation: would you pay for good bits of code explained well by the author?


I have once already: https://www.amazon.com/Beautiful-Code-Leading-Programmers-Pr...

I liked it, but I'm not going to be paying for this sort of thing often. I think a lot would hinge on having content that was high quality, and being able to persuade me that it would be high quality before I paid for it might be challenging.


Thank you very much, challenge accepted


What's interesting is the React team had to implement their own DOM manipulation abstraction, with efficient change management and not interrupting the main JS thread. Their implementation strikes me as a possible general purpose implementation that could eventually replace the way DOM works.


Excellent content. I did find that the code previews in the side bar occasionally changed before or after I expected. I understand the intent with having them adjacent rather than inline ... but I'd probably prefer inline. It would be nice to make this an option of the presentation format.


Is it because you read closer to the top or bottom of the viewport?

I want to add a print mode that would have each code step inline.


I tend to flip back and forth from hacker news articles (e.g. check slack, check build progress). I try to position the page while scrolling so I can find my place back in the text. That alternates from "align top of content section to top of scroll pane" and "align bottom of section content to bottom of scroll pane" depending on the length of the section. I also do it unconsciously as I read, like a habit, to prepare the page in case I need to jump away.

Of the two, I probably favour aligning to the top. But since I alternate I would probably have changed to inline.


I’ve been building apps with something similar but using D3.js (d3-select specifically) for data binding.

https://github.com/ScottORLY/miri


Nice tutorial, but kind of unusable on a mobile device.


I really hate the layout and the annoying, distracting, animated garbage on the left side of the page.

Maybe it isn't rendering properly in my browser, but I would greatly prefer a simple, wide, vertical layout.


I agree, it is simply astounding that the entire thread is filled with praising the presentation style which only gets in the way of the user. Anytime there is a need to add effects, animations, snazzy things - question ruthlessly as to why is it needed. Then after justifying it, ask again.

This is what good documentation looks like: https://golang.org/pkg/

And this: https://www.mpfr.org/mpfr-current/mpfr.html


But this isn't documentation.

This is a tutorial, in which progression and transitioning between steps is a fundamental part of the content. Representing that transition via animations is not inappropriate.


It looks cool, but it is inappropriate because it wastes time since the transitions take time.


Do they take more time than repeating the same 10 or 20 lines of code with slight changes every couple of paragraphs, and having the reader try to figure out what changed since the last 4 times they read almost the same code?


You felt so passionately that you needed to say the same thing three times? This isn’t documentation, think of it more like a slide deck or tutorial. If it’s not your cup of tea, read the source material on Github or look elsewhere for the knowledge. While I somewhat agree with you on it’s a bit overkill, harping on that point repetitively is pointless.


Documentation, presentation, etc. - fundamentally, it is presenting sequential information to the user. And yes, I will say it again, this is NOT the way to do presentations. This is the programming presentation equivalent of designer things like this: https://www.ibm.com/plex/

Absolutely dreadful. But, thanks for the insight and advice about harping on something that I feel passionate about.


> thanks for the insight and advice about harping on something that I feel passionate about.

Given they are helping you out by pointing out a situation where you're being a bit obtuse and socially awkward (and thus helping you avoid similar situations in the future), I'd think that's pretty good. =)


estás loco boludo amazing job


Very nice!


your* ?


Next article: "Build yore own grammar checker" :-)


"Billed your own gram a chequer"


fixed, thanks


You've got a "dependig" in there, too.

"React keeps a linked list with just the fibers that have effects and only visit those fibers." -. should be "visits"


Oh boy there comes a yet another batch of react like “frameworks” no one needs.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: