4 ms·
Show HN: React Oxide: open source ReactJS code editor with tabs, files & webDAV.
- andrewstuart 5y agoHi folks this is React Oxide. It's a minimal code editor that runs in a browser. MIT licensed, code at: https://github.com/bootrino/reactoxide https://github.com/bootrino/reactoxide I wrote React Oxide because I needed a simple code editor but couldn't find something that included editor, tabs, a file tree and file management. You can see a YouTube demo at https://youtu.be/OmxKAWeN38I https://youtu.be/OmxKAWeN38I You can see a live demo at https://www.reactoxide.com https://www.reactoxide.com It use the Microsoft Monaco editor https://microsoft.github.io/monaco-editor/ https://microsoft.github.io/monaco-editor/ It's written in TypeScript. The React code is written in a style I call "Event driven React", which means inter component communication is done via event emitters rather than using global or lifted state. So state is almost entirely managed at a component level. I did this because I find state to make React applications complex and hard to debug, whereas this event driven approach I find easier to understand and write. I would not be surprised if someone comes along and tells me why it's a bad idea, but so far it seems to work - perhaps someone can let me know what the drawbacks are of such an approach.
- beebeepka 5y agoReading your about your style, I can't help but wonder what's the point of using react. You clearly don't like it (and neither do I). Is it purely because nobody seems to care unless a GUI is built with it? You just want to be popular, that it? You should really try using Vue. Everything boils down to event systems anyway
- andrewstuart 5y agoI love React. Cross component communication is always a challenge and the event driven approach just makes React simpler and more fun. How does VueJS solve the problem of cross cutting?
- FractalHQ 5y agoFunny, I came here to insist that you guys try Svelte. They took the best parts of Vue and React, made them so much better, and baked reactivity and state management into JavaScript itself with near 0 overhead or boilerplate. You could learn it in an evening! Anyways, amazing job with this project!
- jacobmischka 5y agoThis short comment thread is hilarious and predictable.
- lf-non 5y agoVue supports observables. So you can have observables that shared across components (for simple use cases). For more involved scenarios, it is possible to libraries like Vuex which offer better visibility/predictability.
- lf-non 5y agoThe issue with using eventemitter for state coordination is that when the UI grows into complexity you run into race conditions where some component isn't showing the right data because it got mounted too late or something somewhere up the hierarchy changed a key and the component got recreated and its state got lost. I guess as long as long as the component hierarchy fits in your head, it is likely straightforward to reason about all the event interactions. The lifted state model ala redux (and similar alternatives) doesn't suffer from this problem. I personally prefer effector [1] these days because it combines the convenience of event emitter with multiple stores and you usually find yourself thinking much less about what changed the store causing my component to rerender much less often. [1] https://effector.dev/ https://effector.dev/
- leetrout 5y agoHave you ever used mobx?
- lf-non 5y agoYes, I love mobx and have used it in a few projects. It is a quite a bit larger and I can live without the transparent reactivity. YMMV.
- brundolf 5y agoSeconding MobX; it elegantly solves most of the issues with events (both maintainability and performance) while also being more ergonomic/concise. I can't praise it enough.
- andrewstuart 5y agoSo far eventemitter has resulted only in simplicity and no race conditions. Perhaps that's because it's a small application.
- jmnicolas 5y ago> There's no error handling at all right now - if any file operation fails then there's no information given, it just goes splat. > There's no tests - and I'm not writing any - I made this project for me and I don't need tests. Not exactly production ready!
- playpause 5y agoRead this: https://news.ycombinator.com/showhn.html https://news.ycombinator.com/showhn.html > Show HN is for something you've made that other people can play with. HN users can try it out, give you feedback, and ask questions in the thread. > A Show HN needn't be complicated or look slick. The community is comfortable with work that's at an early stage.
- have_faith 5y ago> The React code is written in a style I call "Event driven React" How does this differ conceptually from Redux and the general dispatch/reducer architecture? would be interested in reading more about your approach.
- brundolf 5y agoIt seems (OP correct me if I'm wrong) that it uses actual browser events, which are asynchronous (where normally Redux messages are sent and reacted-to synchronously). This probably simplifies things when you do want asynchronous chains of events, but complicates things when it comes to UI consistency and race conditions.
- brianshaler 5y agoThe EventEmitter pattern seems interesting! I can't say I've wrapped my head around it enough to weigh the benefits and drawbacks. I would point out a few things after a quick look: * It looks like you're creating an emitter wrapper around an EventEmitter instance, freezing it, then exporting the instance rather than the frozen wrapper[0]. I see .on() and .off() are wrapped here, while the project appears to use .addListener() and .removeListener() instead. * As a typescript project, I would recommend using typed-emitter[1]. Not only does it ensure you're only emitting recognized events, it ensures that the type of the payload is correct for the corresponding event. Currently, your typed handlers are coercing from `any` as far as your IDE is concerned, rendering it unable to help prevent you from mistakes. * Instead of plumbing an emitter prop everywhere, even through components that don't interact with it directly, this looks like a better fit for the Context pattern to create the global emitter instance in a top-level context provider, then getting a reference to the emitter via useContext[2]. [0] https://github.com/bootrino/reactoxide/blob/master/reactoxide/src/emitter.js https://github.com/bootrino/reactoxide/blob/master/reactoxid... [1] https://www.npmjs.com/package/typed-emitter https://www.npmjs.com/package/typed-emitter [2] https://reactjs.org/docs/context.html https://reactjs.org/docs/context.html
- andrewstuart 5y agoGood advice thanks!