|
|
|
|
|
by lhorie
1845 days ago
|
|
I don't think it makes sense to say "React is a library because you can forego using enough of its features to fall below some arbitrary line". By that logic, I can include Ember in a page and not use any of its features other than `console.log(Ember.VERSION)`, and voila, "it doesn't call you", "it doesn't permeate the codebase", "it doesn't exclude any architectural patterns", therefore it's not a framework. This line of reasoning clearly culminates in reductio ad absurdum. IMHO, it's more fruitful to ponder the possibility that certain projects are not frameworks because they fundamentally lack something that frameworks provide. Suppose we tried to use nothing but lodash to implement a web app. It's certainly doable (given that people write vanilla apps), lodash would "permeate" the codebase and it would probably call a sizable number of your callbacks. But I think we'd both agree lodash is not a framework. But why? I'd argue it's because organizing units (in the "unit test" sense) coherently in a way that is maintainable is outside of its expressed scope. In other words, it's not suitable to that task, even if we wanted it to. React is not only suitable for it, it's specifically designed for that purpose. Speaking of units, another way we can approach this is by looking at where unit boundaries are in comparison to user code boundaries. If you look at any usage of node's `child_process` API, the event handler functions are generally not considered units; the entire child_process instance setup might be one unit, and the event handlers may call other units that are ideally decoupled from whether callback arguments are partial Buffers or error codes and so on. Similarly, a sorting callback is not typically a unit (i.e. you never test that the callback returns 1 or -1, you test that the code sorts correctly instead). React components on the other hand are units in and of themselves. I believe it is accurate to say that frameworks provide abstractions whose purpose is to delineate where a unit boundary is. Components fit that bill perfectly, just as controllers and views and services do in other architectures. |
|
Please note that I’m not arguing that React itself is or isn’t a framework. I’m simply saying that it can be used in multiple and qualitatively different ways, in contrast with your own position in the comment I originally replied to.
In particular, nothing stops you from using React only for what it’s really good at: providing a declarative way to specify the required rendering behaviour, with reasonable modularity due to the component system and reasonable efficiency for many practical applications due to the VDOM. This was the combination of ideas that React popularised within the front-end web development community, the innovation that moved the goalposts in that part of the software industry. You can also use other libraries for what they’re good at, whether that is state management or accessing remote APIs or doing a fuzzy string look-up to power a search box. And you can use your own code to implement your application-specific functionality, as well as delegating to and co-ordinating between these other dependencies whenever it makes sense.
None of this is a novel or React-specific idea. We’ve been building software effectively with modular architectures and separation of concerns for many decades. Isolating presentation code from other aspects is perhaps the most common example, and patterns formalising different arrangements of those responsibilities have been around since at least the 1970s.
I appreciate that this is not necessarily the most trendy or popular way to use React today. There is no shortage of libraries and blog posts and forum comments that actively encourage building your whole application as one big tree of React components, even if those components have little if anything to do with presentation and rendering. But in a discussion about whether modern practices are really a good idea, I think it’s reasonable to point out that there is also no shortage of blog posts and forum comments and Stack Overflow questions asking how to solve problems with that kind of application that wouldn’t have existed in the first place with a better architecture.
It’s very late here so this will be my last comment for tonight, but just to finish, your last paragraph provides some great examples of how different the two approaches we’ve been discussing can be. I absolutely do have unit tests for custom comparison functions in the project I’m working on right now, because there is significant decision-making logic inside them, and if that logic is correct then I can be reasonably confident that the sort using that comparison function will be correct as well. On the other hand, I typically don’t test my React components at all (with that type of unit test) because by design they contain very little logic to be verified.