This content originally appeared on Bits and Pieces - Medium and was authored by Philipp Rembold
This is the first article of a planned mini-series. Stay tuned for the second article, which will cover an actual app with actual functionality.
Recently, I have been obsessed by the ideas of Alen Holub.
He appeared on my radar when I watched the following video of a conversation between him and Robert C. Martin:
In another video on agile architecture (part 1, part 2, about three hours well spent), he explains why and how it is a good thing if a class knows how to render itself; and that notion struck me like a hammer.
Here are a few reasons why this is a good idea:
- There is no ‘god-component’ which keeps everything together. Instead, objects send each other messages, moving from procedural to true object-oriented design
- Changes are highly localized. Instead of changing a model, a view and a controller (as would be necessary in an MVC-architecture) when more attributes are added to a class, you just need to change the class (although that might not mean that there is less code — but the fewer files you change, the easier it is to merge, test and deploy the changes)
- How an object is represented on the UI, which attributes are exposed how is completely up to the class. Having that knowledge inside the class means that the same UI is used uniformly throughout the system (be it one app, a suite of apps or something completely different).
In this article, I want to explore, using a minimal example, how we can design a React app to adhere to this principle. If you want to follow along, create a new react App using react-scripts and copy the source-code from the bottom of the article.
Let’s begin by having a look at the class Counter which is very simple. It has just one attribute count, and is the publisher in a publish-subscribe pattern — that’s what we need the subscribe and unsubscribe methods for. You’ll see that it has a method increment which changes the state of the object.
Then there is the method ‘render’ which returns a react component which is composed of two react components. Both are passed a reference to the instance of the class and not only those parts of the class they are actually interested in.
This is a conscious design decision: passing the whole reference will mean that I don’t need to change the render method if I want to change what the component displays, but only the component(s) itself.
Now, let’s look at the components and how they handle state. The first component just displays the current count, the second one is a button to increment that count.
You’ll notice (as mentioned before) that I didn’t declare the state or the onClick-function explicitly in the interface of the components but rather created a projection on the needed parts of the object and reference the method directly, respectively.
This limits the points of change if later an additional attribute is created in the class and should be used in both components. The IncrementButton component is rather boring; just note that the click-handler is directly tied to the class Note: the click-handler could also be handled as state of the component.
The CounterDisplay component is more interesting, since we can here explore how to handle state.
- the state of the component is declared by constructing a state -object on the fly with the useState-hook.
- using the useEffect-hook, the components registers an observer in the counter class. It makes use of the cleanup-feature of useEffect to also unsubscribe on unMount. This is completely unnecessary in this App, but in the second article we’re going to see a case where it is necessary, and it is good practice to cleanup after oneself. Extracting this to a custom Hook will probably make sense, too; again, wait for the second article to see this in action
- The observer will extract the current state relevant for the component from the object (using a getter — that is generally a bad idea if the getter exposes a field instead of an attribute defining the class; in this case, however, the count defines the class counter and can be exposed; and the getter does not allow access to how the count is implemented). If it has changed, it will update the state and the component re-renders.
Having now seen all the parts, let’s for the fun of it follow what happens when the user opens and uses the app:
- The app function creates a new counter and tells it to render
- The counter renders the display and the button
- The user now presses the button. This fires the click-event and the handler — the increment-method of the counter — changes the state of the class and informs all observers, passing the object itself as payload.
- All observers — in this case, this is only the component CounterDisplay — now query the class for the parts in which they are interested and update their state accordingly.
I hope this article gave you an idea of what I want to achieve with this architecture and how to implement it yourself. Please let me know your thoughts in the comments — and stay tuned for part 2!
Build composable applications
Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favorite frameworks like React or Node. Build scalable and modular applications with a powerful and enjoyable dev experience.
Bring your team to Bit Cloud to host and collaborate on components together, and greatly speed up, scale, and standardize development as a team. Start with composable frontends like a Design System or Micro Frontends, or explore the composable backend. Give it a try →
Learn More
- How We Build Micro Frontends
- How we Build a Component Design System
- The Composable Enterprise: A Guide
An Object-Oriented React App Design was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Philipp Rembold
Philipp Rembold | Sciencx (2022-03-25T12:07:02+00:00) An Object-Oriented React App Design. Retrieved from https://www.scien.cx/2022/03/25/an-object-oriented-react-app-design/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.