3 ms·
I can hardly relate. Perhaps I got lucky, but my experience with the React ecosystem has not been painful. Coming from Angular previously ($watch? isolate scope
by jameslk 11y ago
I can hardly relate. Perhaps I got lucky, but my experience with the React ecosystem has not been painful. Coming from Angular previously ($watch? isolate scope?? transclusion???), it was a breath of fresh air. It might also be due to my avoidance of certain rabbit holes that are prevalent around React.
One of those being the React community's love affair with immutability (immutable.js, Redux, etc). JavaScript is not itself designed around the concept of immutability. Mixing the concepts has only led me to fight with the language and the existing ecosystem. Immutable patterns work best in a world where most things are immutable to begin with, not when you're trying to coerce a world of mutable tools to be immutable.
I'll admit, walking on some of these landmines initially was pretty painful, but I've been working with large codebases in React (SPAs and projects with tens of thousands lines of code) that I feel I've discovered the right paths to take. Here's my takeaways for modern frontend projects using React:
- Keep code organized in modules (a la CommonJS) so code doesn't become a big ball of mud.
- Use React Router to enforce that organization.
- Stick to vanilla JS- ES5/ES6/ES7--it's better documented.
- Use Grunt, and then add in Gulp when needed, otherwise you'll be writing a lot more boilerplate.
- Use Browserify, not Webpack--it doesn't try to do everything.
- Use a reactive data paradigm to keep data flow simple (observables, e.g. Mobservable works really well) instead of Flux/Redux/*ux.
- Stick to real CSS and use namespaces (or web components), not React's hijacked inlined version of it.
These practices have helped the teams I've worked in get stuff done and have scaled quite well.
- dclowd9901 11y agoThere's some trickiness around drizzling data down a hierarchy of views (creating redundant Params for modules) and around action handling outside of Flux (state should live in the controller, so how does a child module pass the action back up gracefully?). How do you addresss those?
- jameslk 11y agoI'm all for uni-directional data flow and React's concept of being explicit by passing data down through props. When it comes to application state however, that's when I whip out React's context (now documented https://facebook.github.io/react/docs/context.html https://facebook.github.io/react/docs/context.html). I follow the pattern of Redux/Baobab of having a monolithic state and partitioning it by module namespace (to avoid data dependency issues, e.g. Flux's waitFor hell http://christianalfoni.github.io/javascript/2015/02/06/plant-a-baobab-tree-in-your-flux-application.html http://christianalfoni.github.io/javascript/2015/02/06/plant...). Each module manages its slice of state and exposes an API for encapsulation. This also plays really well with React Router. In other words, the application state and the actions that can be performed on the state are passed down through the context. I prefer Redux's concept of smart/dumb components (https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.t5fhdnhsc https://medium.com/@dan_abramov/smart-and-dumb-components-7c...) to make sure the application state isn't being spaghettied all over the code. With Mobservable, there's a specific part of their documentation which I think does a decent job of explaining a similar set up: https://mweststrate.github.io/mobservable/best/store.html https://mweststrate.github.io/mobservable/best/store.html