8 ms·
Hi HN. I built Forgo because React is no longer "it's just JS" (actually it never was). The patterns, practices and vocabulary used in the React ecosystem prese
by jeswin 6y ago
Hi HN. I built Forgo because React is no longer "it's just JS" (actually it never was). The patterns, practices and vocabulary used in the React ecosystem present considerable hurdles to a newbie - hooks, reducers, actions, flux etc. All of them are React specific, and locks the developer into framework related knowledge.
But there is one idea from React which made a ton of sense; from the time I started using it nearly seven years back. That's JSX - instead of shoehorning expressions into markup, move markup into the programming language. Forgo embraces JSX and skips most of the other ideas in React in favor of a more plain vanilla approach.
- chrisabrams 6y agoI don't consider reducers, actions, redux/flux to be React specific, even if they are popular in the React world. I know just as many people who don't use those in the React world. IMO what React did was push forward the single data flow paradigm. What should a developer do that needs to share state across a Forgo app? It would be awesome if browsers just had a real template language like JSX, we'd see more "web components" which are just a little bit of JSX/or whatever templates and some DOM APIs. Developers are tired of managing binding and unbinding events. React does that well. I assume Fargo does too. So putting aside the redux/flux paradigm, what else is the real hurdle being solved?
- jeswin 6y ago> What should a developer do that needs to share state across a Forgo app? We already have many facilities in JS to handle state. Singleton patterns, closures etc. The example on the website uses closures to handle component state - which is simpler than React's hooks based approach. function SimpleTimer() { let seconds = 0; // Just a plain variable return { render(props, args) { setTimeout(() => { seconds++; rerender(args.element); // rerender! }, 1000); return <div>{seconds} secs have elapsed...</div>; }, }; } > I don't consider reducers, actions, redux/flux to be React specific They didn't emerge from React - but it isn't possible to do React without them. When I conduct trainings, I often see some of my students go - wow, why would you do that? So Forgo basically is an exploration of how to simplify things - and to let users pick their desired level of complexity.
- dceddia 6y agoI understand where the Redux terminology gets mixed up with React and people believe they're one and the same, but it's totally possible to do React without touching reducers, actions, or Redux. Maybe you mean it's not realistic to write React "beyond toy examples" or "in the real world" without Redux, but still, I'd beg to differ there. You can get very far with plain React and the context API and other libraries. Redux definitely isn't required. Forgo does look cool though! I like the idea of using plain variables for state, and returning an object allows you to add other things to that object (didMount, didUpdate, unmount etc).
- michaelpb 6y agoYeah, even with large-ish projects, just by refactoring some of your state manipulation into separate libraries that you manually hook into your top-level components, you can get by quite fine without a whiff of Redux. That said, this is a cool framework, congrats on completing it! I'm also working on a minimalist React-ish framework though in a very different approach.
- chrisabrams 6y ago> They didn't emerge from React - but it isn't possible to do React without them. It is 100% possible to build large React apps without redux/flux. There are entire ecosystems built around, say Mobx, among many other libraries and tools which don't even follow the flux style patterns. > The example on the website uses closures to handle component state I'm not asking about component state; I'm asking how do multiple components access app-wide state. I can't use a singleton for that; how do I know when that singleton is updated? I guess I could use a proxy but I don't want to do that. > and to let users pick their desired level of complexity. React is the view layer. It doesn't enforce any type of data layer or state management layer.
- jeswin 6y ago> I can't use a singleton for that; how do I know when that singleton is updated? It's up to the developer to make that decision. An AccountInfo control could be listening to "ACCOUNT_INFO_CHANGE" events (emitted when account info changes), and can subsequently rerender and read off some singleton state. Rerenders are explicit. And like you said, proxies could be another option.
- spankalee 6y agoI work on a templating library called lit-html that aims to just solve the declarative DOM w/ property & events bindings problem: https://lit-html.polymer-project.org/ https://lit-html.polymer-project.org/ It's plain JS with a very similar DX to JSX, and I think addresses that really well. My team also works closely with Chrome, Safari, and Firefox on proposals like Template Instantiation that aim to build up more APIs that template libraries can use to be smaller, faster, and more interoperable. I really think we will eventually get good templating in the DOM so at least the most common use-cases are taken care of.
- no_wizard 6y agoWhere is the working group at with that proposal? I've been eyeing it closely, but it hasn't seen any significant movement in over two years, last I checked. I'm excited about template instantiate, though I worry the API is going to be tied to having template element instances, instead of being part of the HTMLTemplateElement and its own thing I could take advantage of with string templates. I also haven't seen any place where I can give feedback formally on the proposal to the working group :( HTML imports were supposed to be the holy grail to solve this, but nobody but Chrome supported it :(
- spankalee 6y agoIt's being discussed mainly in the WICG web components GitHub repo. There are recent issues in here: https://github.com/WICG/webcomponents/issues https://github.com/WICG/webcomponents/issues
- eyelidlessness 6y agoEvery time I look at lit I get this unsettling feeling that it’s almost what I want but can’t be, because it loses the only thing I want in JSX. Lit fundamentally targets templates with HTML output. Which is great for what it is. But the thing JSX offers that nothing else does is: - return values are a data structure, so they’re render-target/render-implementation agnostic - it’s compile time only/effectively a macro, so the compiler can choose how to render subtrees I love the “it’s actually part of the language not a build tool” part of lit, but it can’t satisfy those other goals without giving up its core selling points.
- varispeed 6y agoReact is nothing new - these patterns that are being used have been with us for decades. Sure you can go about programming without knowing these patterns, but looking for ways around in order to know and understand less is a dead end. If you can't understand what hooks, reducers or actions do, why not spending more time on it? Sooner or later a newbie will encounter more complex project and having themselves shielded from knowledge will likely cause them to give up.
- gfxgirl 6y agoHooks IMO are a poor design. Calling a function that does something different with the same parameters is an anti-pattern. const [v, setV] = useState(123); First call v gets set to 123, second call it doesn't. WAT!
- nwienert 6y agoWhat? Functions can do anything, even outside of hooks you can have memoized functions. Algebraic Effects are the thing I'm most glad React introduced, hooks are nothing short of a revolution for UI.
- eyelidlessness 6y agoFunctions which return different data for the same input aren’t functions. It’s a bad interface.
- Chernobog 6y agoThat's a very general statement. I wouldn't accuse you of implying that it would also apply to e.g. Date.now(), but I firmly disagree that it applies to hooks. I get that hooks are declared in the form of functions, and that pure functions are the desired pattern in many cases. But I like to think of hooks as hooks, not functions (emphasized by the naming convention of prefixing with "use"). We are in the context of React, after all, and I think it is comparable to critique of JSX because of "separation of concerns". Yes, valid critique in many cases, but not necessarily applicable to React. Having been a React developer for over 5 years now, I think hooks solve a lot of problems that before would typically have been solved with Redux, Redux Saga and other libraries. Or with home made solutions, leading to various degrees of mess. From what I've seen, hooks have enabled React devs to write code that is even easier to understand, while also keeping things simpler and external libraries fewer.
- spankalee 6y agoJSX isn't "just JS" either. Did you consider using plain JS? You can still move markup into script.
- k__ 6y agoYes, the arguments here are ridiculous. Everything that IS actually just JS is listed (hooks, actions, reducers), but the only thing that isnt (JSX) is used without a question. Sometimes React critique just reads like an elaborate trolling attempt.
- eyelidlessness 6y agoJSX being a macro-like compile time primitive is actually its biggest strength. It’s a data structure but its implementation is undefined, so JSX implementations are free to compile it to whatever is most suitable for its runtime. Including compiling it away to nothing. “It’s just JS” can certainly do that but you need additional compile time signals.
- keyle 6y agoI'm on the opposite side. I think JSX is a horror show. We've been trying to remove view from logic since the 90s, and move towards declarative views with data binding. Keep your nook and crannies away from the presentation layer. But all the industry wants is shoving PHP in the browser. I think it's sad. We're making the UI layer always more complicated. Let's say your UI changes, like a redesign... you can rewrite your component and probably need to change most of them. If your UI was just dumb and declarative and the data was salt on top, changing the UI is trivial. The UI should declare what the UI should look like, not describe how it should do it. This is why, as an old timer, I much prefer the direction VueJS took. Edit: great lib though, anything small is a win.
- postalrat 6y agoTill you want to render a list or something. Then your vue template starts looking a lot more like javascript.
- keyle 6y agoThat's plain wrong, it's still all inline with the markup, and more importantly, it doesn't reveal any of the inner working of the list.
- daveidol 6y agoPeople always talk about separation of HTML and JS is a separation of concerns, but it's really not in my experience. It's separation of technologies. The JS has to grab DOM nodes by class or ID and is highly coupled to its structure anyway, so putting them together (as React does) seems far more logical in my opinion. Separating them into files and using string classes to look them up is far less easier to read and leads to runtime issues (since a typo isn't actually a code error but just silently doesn't work). JSX is really not like PHP at all. PHP just writes out strings - JSX is all JavaScript objects. What you are describing is more akin to something like Handlebars or Angular templates. Plus, JSX is just sugar and is not required to use React if you prefer something like hyperscript (no compile step needed in that case).
- catacombs 6y agoThanks for the implementation. How does Forgo handle state?
- arendtio 6y agoActually, JSX is the thing that keeps me from using React ;-) I prefer the template syntax of .vue files or similar to the one riot.js uses. They use basically the same syntax html uses, just on a smaller scale and limited to a single component. That way you don't have to invent new was of embedding markup in code.
- eyelidlessness 6y agoI’m curious if you’ve looked at SolidJS, which has similar goals.