When I first started using Reagent, I was surprised to see the use of React class components. Whenever needing to hook
into the component lifecycle for things like add and removing event listeners, we were using componentDidMount() and
componentWillUnmount(). Hooks and function components have been a part of React since 2018, and the React developers
themselves have all but deprecated class components when they launched
the new React documentation website in 2023. Documentation on how to use class components in React
is now under the "Legacy API" section of the website. Modern React is functional and immutable, yet when writing React
in the functional and immutable realm of ClojureScript, we are using Object-Oriented class components and mutating
atoms.
The solution to your re-rendering woes.
Those familiar with the C3kit Bucket library have come to love the c3kit.bucket.memory implementation. It allows us to easily mock out our database when writing tests on the backend simply by switching implementations, and on the front end we can use a Reagent atom for the database store and our components will re-render automagically whenever data in the database changes. It also means we are using the same db/find and db/tx syntax whether we are interacting with the actual backend database or the front end state.
While this Reagent usage is convenient, it's not without its share of problems. The fact that the database store is a Reagent atom means that if anything changes in the database, it will cause all components that are doing a db/find to re-render, even if they are querying for data unrelated to the data that was modified. This means that something as simple as opening a modal could cause every component
| (ns scratch-7 | |
| (:require [reagent.core :as reagent] | |
| [reagent.dom :as dom] | |
| [react :as react])) | |
| (defn noop | |
| "Does nothing, returns nil" | |
| []) | |
| (defn highlight-code [node] "Highlight code snippets") |