Dev log
Published: 2024-04-29 07:40:24

feature: it's user interactions that store, update and manipulate data. It processes the data from UI to database to store it, and it extracts some data from database and process them to transfer them to the users. 
<Link/> component does nothing about this, it's just about navigation. so I'll put them just right there.


changing color animation

layout: client component renders server components(or client components) as props.


## Building progress animation
1. changing color on button click: impossible since we cannot transfer props to the children. If we change them to client components, we're bound to give up all the performance benefits since all the rendered components become client components.
2. changing the color on pathname

## AutoAnimate
new update: AutoAnimate juggles elements when you use the same values for the array. Since it just works, I can create an array based on the current `pathname`.

## font optimization in client components

## Link component

Using Link optimizes the performance by prefetching the route. That is why they recommend using `<Link />` components rather than `useRouter()` hook.


## Enum to array
you can extract the values of enum using `Object.values(Enum)`.

## Setting up Zustand

- global store shouldn't be used anymore; Multiple requests have their store using contexts instead of persisting them as a module state. 
- Both Server components render and Client components render. Since their outputs are different(`store` is set to default values in server components, hydration errors are thrown(local data storage, local fetch).
By initializing the Store in SSR, it can keep

## Should I use Form elements?
- If you get data across multiple pages and only send data to the server on the last page. In this situation, is it recommended to use form elements for each page?
- There is no standard saying that form elements must include control elements and a submit button.
- [w3.org](https://www.w3.org/WAI/tutorials/forms/multi-page/) actually says it's even better to split a long form into smaller pieces. Therefore, it looks like it's a good practice to use form elements across multiple pages.

## Why `@vis.gl/react-google-maps`?

![Library Comparison Table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tukyqpemjjtccgo92rc3.png)
- Can draw on the map
- Still being maintained by the community
- Only 3 bugs discovered
- Use hook to be in sync with the google maps state

## Environment variables

Next.js will load environment variables from `.env.local` file.

- If the name of an environment variable doesn't start with `NEXT_PUBLIC`, it is only accessible on the server. That means if a client component attempts to access it, it'll be `undefined`. Therefore, the rendered result would be different from the server and there might be a hydration error.
- If the name of environment variable starts with `NEXT_PUBLIC`, Next.js replaces all the `process.env.[variable]` with the given value. That's why client components can also access environment variables.
 

.refine
When you need to customize with your own rules, you can use `.refine()` method.
some methods take errorMap instead of errorMessage itself.

```tsx
const getEnvVariable = (key: string) => {
  console.log(key); // "BASE_URL"
  console.log(process.env[key]); // undefined
  console.log(process.env["BASE_URL"]); // http://localhost:3000

  if (process.env[key] === undefined) {
    throw new Error(`Environment variable is undefined`);
  }
  return process.env[key];
};
```
Why??

# MSW Troubleshooting

## Hot Module Reloading problems caused by Next.js Architecture
If you're using next.js, you must run `msw` on the client and server side. The problem comes into play when you change the `handler` of MSW. Next.js will not refresh on handler updates. Here's why.
Next.js 14 manages two processes. One is a long-term process and it's used for updating RootLayout. The other one is a short-term process used for updating relatively small routes. **Since MSW is registered as a global module, the long-term process manages MSW. However, processes don't share memory. Therefore, Next.js doesn't refresh the short-term process.**

## Strategic Decision
I still decided to use MSW for mocking APIs because Hot Module Reloading is not a serious problem. Since I'll develop each component using Storybook in isolation, the dev server doesn't need fresh updates. So I'll keep using MSW to see the result in the dev server when all the components get together.

## Instrumention
If you want to run some code every time Next.js starts running, you can `register()` it. This feature is typically used for integrating Next.js and logging/monitoring tools.

### Cannot find module msw/node

You should set up next.config.js to enable instrumentation.

```js
module.exports = {
  experimental: {
    instrumentationHook: true,
  }
}
```

However, I got "Cannot find module msw/node" error even though I set it up with the option. The doc says 'Place the file in the root of your application or inside an src folder if using on'. I followed [the Feature-Sliced Design's convention](https://feature-sliced.design/docs/guides/tech/with-nextjs), which looks like the following image.

![Directory Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onylx4g13x9dkef2h6vg.png)

When I set up Next.js initially, I chose the root directory option, so I thought "Cannot find module 'msw/node'" was thrown, and after many trials and errors, I found out I should have placed the file in the `/src` directory.

### Cannot find module msw/browser
To make the example code more tidy, I refactored it with 'early return' approach.

```tsx
export async function enableMocking() {
  // early return doesn't work
  if (
    typeof window === "undefined" ||
    process.env.NODE_ENV !== "development"
  ) {
    return;
  }
  const { worker } = await import("@/mocks/browser");
  await worker.start();
}
```

It kept throwing `Cannot find module msw/browser`. I attempted to change the path of the dynamic import to the relative one without using the path alias and set up package.json. However, it came down to this early return pattern. If I avoid this approach, my app runs with the error on the client side.

```tsx
// Next.js picks up instrumentation.ts file in /src directory
export async function enableMocking() {
  // early return doesn't work
  if (
    typeof window !== "undefined" &&
    process.env.NODE_ENV === "development"
  ) {
    const { worker } = await 
    import("@/mocks/browser");
    await worker.start();
  }
}
```

As a side note: I had the same problem with the server-side configuration. **If you know something about this problem, please let me know.**