Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add article about React components #288

Merged
merged 4 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions content/i-write-big-react-components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: 'I write big React components'
publishedAt: '2024-03-15'
summary: 'Learn why large React components are not a problem and how to think about component size correctly.'
---

<Callout emoji="💡">
Learn why large React components are not a problem and how to think about component size correctly.
</Callout>

When reading articles about React best practices, you’ll learn that it’s better to keep your components small (numbers can vary, but usually 150–200 lines of code is what recommended). The problem is that most articles don't properly explain the reasoning behind this thing, and if followed blindly, it can do more harm than good. So here is my explanation.

First, and probably most important, instead of thinking about lines of code, you should think about component responsibilities. If your component has a single responsibility, then it’ll be 99% fine to keep things together, no matter how many lines of code it is. And in the case of multiple responsibilities, you’ll most likely want to split the component into smaller pieces that are responsible for a single thing.

Separating a single component with multiple responsibilities usually comes with performance benefits. Multiple responsibilities mean multiple reasons for a component to re-render, and sometimes it’s not optimal to re-render the whole component’s UI when a tiny piece of state changed. Having components with single responsibilities, you can expect that the UI is updated when it really needed to be updated.

Obviously, it’s easier to work with a component (read/modify) that has a single responsibility. But at the same time, by refactoring such components into smaller pieces you increase cognitive load (it might be nice to read this top-level piece with a high level of abstractions where everything is moved into custom hooks and subcomponents, but it means more pieces to keep in your head when actually making changes and trying to drill down into all these layers of abstraction).

In conclusion, I would say that exceptions are possible in both cases. By separating a component into smaller pieces you increase tree nesting which might have its own performance downsides as well as a single large component can have higher time to instantiation, but I hope that now you have a small framework helping you to decide whether to refactor a component into smaller pieces or not.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/blog/ViewCounter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface Props {
}

async function ViewCounter({ slug }: Props) {
const blogPostViews = await getBlogPostViews();
const blogPostViews = await getBlogPostViews(slug);

const views = blogPostViews[slug];

Expand Down
2 changes: 1 addition & 1 deletion src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ a {
}

.prose pre {
@apply border border-neutral-800 bg-neutral-900;
@apply border border-neutral-800 !bg-neutral-900;
}

.prose code {
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BASE_URL } from '../utils/const';
import { OG_IMAGE } from '../utils/ogImages';

export const metadata: Metadata = {
title: 'kkurko.dev',
title: 'Kirill Kurko',
description: 'Frontend Developer and Penguin 🐧',
openGraph: {
url: new URL(BASE_URL),
Expand Down
10 changes: 7 additions & 3 deletions src/lib/models/blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ export function getAllBlogPosts() {
});
}

export async function getBlogPostViews() {
export async function getBlogPostViews(slug: string) {
noStore();

const views = await prisma.blog.findMany();
const blogViews = await prisma.blog.findFirst({
where: {
slug,
},
});

return Object.fromEntries(views.map((view) => [view.slug, view.views]));
return { [slug]: blogViews?.views ?? 0 };
}

export async function trackView(slug: string) {
Expand Down
Loading