Ask HN: How can we make React better?
I work on React. We have our own ideas on where we'd like to take the project (see https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html), but we always like to hear from larger communities too.
Whether you use React now, tried it in the past, or decided not to try it – what could make React better for you?
62 comments
[ 3.6 ms ] story [ 106 ms ] threadI know Facebook has an internal CSS Module thing that is not open source ready. So this has been pushed off to user land. However, lack of an officially blessed style solution makes React components less reusable across projects compared to Vue. Thanks to vue-loader, the Vue community can focus on other things. I am NOT advocating for single file components like Vue, I am hoping that FB can just bless a solution so we can move forward as community.
I'm really quite pleased Vue sort applied the component approach to styles by slapping them in the component file and then left it at that.
But if OP reads this comment, I outlined it here:
https://stackoverflow.com/questions/52636618/modifying-react...
https://github.com/facebook/react/issues/6348
It may be an ecosystem problem but I think the big projects have an obligation to set the tone for what is acceptable elsewhere and not just jump on the next wizbang thing that’s marginally better or more correct.
Pros and cons but I see the cost of maintenance being very high in client side js compared to backend.
The frontend ecosystem is definitely less mature than backend. Gmail and Google Maps, two of the first "real" client-side applications, were launched in 2004 and 2005 – so the entire ecosystem is really about a dozen years old. Before that people didn’t really “realize” that JS and web was a real programming environment. That means there's a lot to catch up on and a lot to experiment with as people figure out the best ways to build things. Compare this to backend or infrastructure development which have had decades to develop.
That said – I completely recognize that this can be painful. You don't always need to use the latest stuff though. If a "less fashionable" technology does the job for you, you can definitely use it. And trying to mitigate some of this complexity is why my team works on projects like Create React App which (whether or not you're using React) can insulate you from some of the "churn" that people often feel in the ecosystem.
In React itself, we try to have as few breaking changes as possible. (And our team needs to keep 50,000 components at Facebook working through our changes, which is a major incentive to not break things unnecessarily.) Our last major release, React 16, was released in Sep 2017. But it actually included almost no breakages (we mostly bumped the version number out of caution because it included a huge number of internal refactors). So I'd say our last "actually breaking" release was React 15, in Apr 2016, about 2.5 years ago. React 17 will probably be released sometime next year, so we're talking 3-ish years between releases. I think it's hard to do much better than that without stopping forward progress. Note that if we don't improve React quickly enough people will abandon it for another (incompatible) library, which doesn't really solve your problem either. So we try our best to make sure we're working on (what we think are) the right things and do our best to get it right the first time.
(React could stop being developed, as could Vue. In both cases, you or anyone else could pick it up and build upon the last version.)
they can still relicense it in the future if they manage to kill off their competition. At that point I'd have to hope that someone will fork a pre license change version. Don't want to risk dealing with that crap don't want to support facebook.
1. More strictness in terms of what is and is not valid JSX. Just today I was working on a React Native app that compiled for iOS but not Android. The issue ended up being a stray semicolon, leading to syntactically incorrect code that allowed for a valid iOS build anyway. I would expect it to fail regardless of environment. The error was also very cryptic although this probably has more to do with React Native than React [1].
2. More proactive warnings at runtime for development builds. React does a great job at telling me what I'm doing wrong; I'd also like it to tell me what I could be doing better. Some ideas are cyclomatic complexity warnings to detect when there is too much branching logic in a component or warnings that indicate that a component is getting too large and could be refactored.
3. Rebuilding the virtual DOM in WebAssembly. Now this might be excessive as React performs quite well in my experience. But it could lead to performance and portability benefits as well as just be a cool project to work on. Mozilla published an article today regarding gains in JS and WebAssembly interop performance; check it out if you haven't [2].
[1] https://github.com/facebook/react-native/issues/13243
[2] https://hacks.mozilla.org/2018/10/calls-between-javascript-a...
Warning for things that aren’t errors seems like a slippery slope and one where false positives could be very annoying, but it’s an interesting request. For the specific problem of large, confusing components, we have some ideas about how to help make these more manageable that you’ll hopefully hear about soon.
React implemented in WASM is also a fun possibility but not one that we’ve started on yet. :)
https://www.youtube.com/watch?v=3GHJ4cbxsVQ
For this i'll actually reach for Preact instead. Or perhaps even the relatively new Svelte (disappearing) framework.
However we do try to keep the size down; for example React 16 included a 30% size reduction.
When you say "the overhead of react is far too great" are you speaking from something you tried that didn't work? I haven't heard any stories like this so would be interested to hear more if React was actually too slow for you.
(We're also working on our own optimizing compiler, but it's still a very experimental project at this stage.)
I'd love to see React itself ship with options to drop polyfills and old browser support if it helps the bundle size.
One thing that is somehow frustrating with multiple repositories are those shared components.
I know this is not directly an issue with react itself but after create-react-app one, two, three. ... times the amount of duplicated code/components become a huge debt.
I'm not sure I need something new/different from react@next but guidelines for creating libraries and produce high quality components (type definition done right for example) is something that I'd like to have.
React Native is so good and so similar to front end web work (including integrating native libraries, it was downright joyful once I figured it out) that the experience of setting up the most basic email/password authentication scheme really stood out. This is true to some extent throughout the native landscape (that it's a little more complicated than web pages), but still.
I think some might argue that this belongs in an external library, and maybe so, but I think there needs to be an easy to use standard library or framework component that keeps in mind what the developer experience is on the web.
React Native is still my first choice for a small-medium native app project, a good authentication story would put it on another level. Also note the last time this came up for me was a year ago so maybe there has been improvement.
So maybe you can pass forward refs from A to all the C's and then bypass B in the cases you want to directly trigger rerender on the individual affected C components. Is that the way to handle this scenario?
It's pretty late so the above maybe doesn't make sense, but to try to summarize, having a solution for updating deeply nested children without diffing all of the related components to see if they need rerender.
If that’s not fast enough, perhaps it would be faster to directly subscribe each instance of C to its state updates with something like Redux’ connect HOC. I assume that React does something like marking branches of the component tree as dirty and only doing a render pass on the dirty sections, but I could be wrong. If I’m correct, that would give you direct rerenders of the individual deeply nested C instances without rerendering A or B or unchanged C components at all.
Promote harmony, cross-compatibility, and longevity in the web development landscape.
If you have any animation where you want to tween the state yourself (say changing position as a function of time), then that requires updating the state at 60fps or whatever requestAnimationFrame goes at.
It feels philosophically wrong to do that under the declarative paradigm of react. React is supposed to be responsible for taking the state and "transitioning"(or diffing) the dom to the new state. By doing the tweening myself, it feels like I am polluting the state with a lot of transient junk (like current progress time, start/end keyframe states, entering/exiting elements, etc). This is especially bad if you want to be a redux purist and throw all my state into a global state! But at the same time I don't know where else I can put it.
I've completely avoided doing anything more complicated than a CSS transition since coming to react (long ago, which also means there could be better 3rd party libraries that solves this problem now that I don't know of). But is there a better way to make this work out of the box?
Regarding the handling of timers, easing functions, etc., that does need to be handled somewhere, but it can be “componentized” so that you can reuse animation logic via a friendly component API without worrying about the underlying bookkeeping. You’ll have to learn and get used to that API, but when you find one that works for you it can be great. Two popular such libraries for React are react-spring and Pose:
http://react-spring.surge.sh/spring
https://popmotion.io/pose/learn/popmotion-get-started/
No longer actively maintained, though, so you might want to check out https://github.com/aholachek/react-flip-toolkit instead.
I wish for media queries and keyframes (and other CSS tidbits) to be possible in React JS styles, so that I stop hopping between different CSS module libraries.
I would focus on making React stable, fast and lightweight but improve on tooling and ecosystem around it.
* I would like blessed way of extracting React components, so they can be reused between projects (like right click in IDE and share) - something like https://bitsrc.io/
* react addon for chrome could be much nicer (I have to dig through so many unnamed HoC sometimes).
* you could favor more beginner friendly state solution - something like https://github.com/solkimicreb/react-easy-state
* you could embrace typescript for easier usage experience
There could be some React plugin(kinda like http://demo.rekit.org/) for editors that would allow for:
* adding mock props to component and preview it on hover, click for example (kinda like styleguidist but with less setup overhead) * abuse above to provide out of the box image snapshot testing * simpler ability to add tests (like right click on component and "add assertion", "go to test") * some structured way of making components * swap between style, tests, data sources and logic * run tests only for this component * etc - basically more streamlined creation experience
Also please focus on debugging when introducing async rendering. (so there won't be errors out of nowhere in stack trace)
In my experience it doesn't help people, especially at an earlier stage, but rather clutters what people already know about JavaScript. It causes tooling to slow down and ultimately doesn't prevent bugs that could not already be caught by good design and linting.
I'm much more of a fan of something like PropTypes, which isn't just superficial, but actually runs on your code in all places and will stop you passing the wrong types to components, regardless of what environment you're in.
Otherwise everything else on this list is a +1
TypeScript doesn't prevent any bugs that tests would not, but it does so faster and more concisely.
Tooling slowdown depends on your tooling setup; TypeScript can compile JSX on its own.
PropTypes are useful if you're transitioning from a plain JS codebase. But if you can start with and go full TS, I highly recommend going that route.
Currently it's a DOM management library that runs like a in-browser plugin, basically hijacking the browser, with tendencies to be a cross-platform native tool.
Realistically, it's a bloated view layer with a huge runtime (React + React DOM are ~100k minified).
While performance on iOS is good, the Android experience is horribly slow and full of bugs. What people like about it is the yoga layout engine primarily.
So basically you have a 100k runtime at minimum + a questionably maintainable, and definetly not a reusable native aspect of it.
<input model={myJsObject.text} /> or <input bindValue={myJsObject.text} />
At least for standard HTML components this should work, as they would only have one editable property.
Deal with state better, currently if you have anything more than a list of todos, react grinds to a halt. It’s completely unable to deal with a realistic amount of state. Side note: this is really weird since react is very fond of state. I’ve tried redux and it just makes everything worse by adding in more checks that can only handle identity checks with any sort of efficiency.
Lastly react prevents me using a lot of existing js because it interferes with the lifecycle in react, or manipulates the dom directly. This makes working with react much less efficient than writing plain js.