Every single framework you encounter will need to answer a few different questions:
- Routing
- State Management
- How to manage local app state
- How to fetch and persist state from the server
- HTML Generation
- Styling
React
- Routing
- Not a React Concern, use a library or a framework that builds on React
- react-router
- NextJS pages / app folder
- etc..
- Not a React Concern, use a library or a framework that builds on React
- State Management
- Components are laid out in a tree
- State flows down from a parent node to the child components.
- I say parent node and not component because parent nodes can be state stores or a server or anything that passes info down in to a child component
- Server State
- Can be stored in the same state management library or approach you've chosen
- Projects have moved on to react-query, useSWR, or a mixture of the two plus server side rendering.
- In either case the thinking nowadays is to keep your query data separate from your local app data
- General guidelines
- Keep state as close as possible to the components using it.
- This prevent unnecessary renders of the subscribing component's subtree.
- Decouple your business logic from the presentation state
- Know the size of your application
- Atoms work for smaller applications but without a proper organization structure can become unwieldy
- Redux style structures are probably more overhead than necessary in small to medium applications but really start to shine as your application becomes larger or if you have state that can be updated from many different places. Having explicit actions helps traceability
- MobX or Proxy based stores can be more performant out of the box because they keep track of the actual state you're reading and will only re-render the leaf nodes when the state changes.
- Keep state as close as possible to the components using it.
- HTML Generation
- Component Based
- JSX -> HTML
- Props + State => view
- Components are composed to create larger pages / features
- Component Based
- Styling
- Not opinionated
- Throughout the history of react there have been several approaches each lauded as the right solution at the time.
- Use a global stylesheet like pre-react days.
- Use CSS Modules
- This adds a namespace to your css or generates unique keys to encourage encapsulation
- This is where we start to go against the CSS cascade somewhat, we're limiting the "reach" of the cascade to avoid the case where we update the CSS in one place and inadvertently affect other components.
- Styled Components and Other CSS-in-JS solutions
- These libraries offer a way to write CSS directly in your JavaScript, allowing you to take advantage of JavaScript's full power to dynamically create and apply styles.
- They aim to enhance CSS for styling React component systems. Styled-components, for instance, leverages tagged template literals to style your components.
- It comes with benefits like automatic critical CSS, no class name bugs, easier deletion of CSS, and dynamic styling adapting to your props.
- Utility based CSS
- These are CSS libraries like Tailwind CSS that provide low-level utility classes that let you build completely custom designs without ever leaving your HTML.
- The idea behind utility-first CSS is to compose your design directly in your markup. It leads to less context switching than having separate CSS files or even CSS-in-JS.
- Tailwind, for example, also allows you to customize your design system (colors, spacing, etc.) directly in a configuration file.
In future write ups we will explore other frameworks and how they answer these concerns.
Top comments (0)