<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Lada496 on Medium]]></title>
        <description><![CDATA[Stories by Lada496 on Medium]]></description>
        <link>https://medium.com/@lada496?source=rss-26c837ad3dc8------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*dmbNkD5D-u45r44go_cf0g.png</url>
            <title>Stories by Lada496 on Medium</title>
            <link>https://medium.com/@lada496?source=rss-26c837ad3dc8------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 08 Jun 2026 11:19:14 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@lada496/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Favorite Toggle Button with useOptimistic]]></title>
            <link>https://medium.com/@lada496/favorite-toggle-button-with-useoptimistic-0c6f7a0e18f4?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/0c6f7a0e18f4</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[nextjs]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Mon, 02 Sep 2024 07:41:09 GMT</pubDate>
            <atom:updated>2025-05-12T17:58:15.317Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*zflBXzg8prmacm7lArlAPA.gif" /></figure><p>This is an idea of implementing a toggle button with useOptimistic. useOptimistic is a React experimental hook that allows apps to update UI optimistically while the actual state updates with async operation. You can learn more about it with those links.</p><ul><li><a href="https://react.dev/reference/react/useOptimistic">useOptimistic - React</a></li><li><a href="https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#optimistic-updates">Data Fetching: Server Actions and Mutations | Next.js</a></li></ul><p>Here is the main code of my component.</p><pre>import { useOptimistic, useRef } from &#39;react&#39;<br>import { Button } from &#39;./ui/button&#39;<br>import { HeartIcon, HeartFilledIcon } from &#39;@radix-ui/react-icons&#39;<br><br>export function FavoriteButton({<br>  isFavorite,<br>  placeId,<br>}: {<br>  isFavorite: boolean<br>  placeId: string<br>}) {<br>  <br>  async function formAction(formData: FormData) {<br>    addOptimisticFavorite(!isFavorite)<br>    formRef.current?.reset()<br>    const placeId = formData.get(&#39;placeId&#39;)<br>    await fetch(`/api/favorite`, {<br>      method: &#39;POST&#39;,<br>      body: JSON.stringify({ placeId }),<br>    })<br>  }<br><br>  const [optimisticIsFavorite, addOptimisticFavorite] = useOptimistic(<br>    isFavorite,<br>    (state) =&gt; !state,<br>  )<br>  return (<br>    &lt;form action={formAction} ref={formRef}&gt;<br>      &lt;input type=&quot;hidden&quot; value={placeId} name=&quot;placeId&quot; /&gt;<br>      &lt;Button variant=&quot;ghost&quot; type=&quot;submit&quot; onClick={handleClick}&gt;<br>        {optimisticIsFavorite ? &lt;HeartFilledIcon /&gt; : &lt;HeartIcon /&gt;}<br>      &lt;/Button&gt;<br>    &lt;/form&gt;<br>  )<br>}</pre><p>optimisticFavorite toggles immediately after users click the button and gets rolled back when the component receives isFavoritewhose value is different from optimisticFavorite. Otherwise, optimisticFavorite keeps the client-side state.</p><p>In my real code, unfortunately, I needed to deal with two different cases to update isFavorite in my app, which is not ideal, and the code gets a little messy. Please visit the link below if you’re interested.</p><p><a href="https://github.com/AI-Gourmet-Navigator/ai-gourmet-navigator/blob/main/src/components/favorite-button.tsx">ai-gourmet-navigator/src/components/favorite-button.tsx at main · AI-Gourmet-Navigator/ai-gourmet-navigator</a></p><p>That’s it! Thank you for reading :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0c6f7a0e18f4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Storybook ❎ NextAuth: How to set mock auth session]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-snippet">This is my memo when I write stories that change depending on session states.</p><p class="medium-feed-link"><a href="https://medium.com/@lada496/storybook-%EF%BD%98nextauth-how-to-set-mock-auth-session-d1d3c0237e52?source=rss-26c837ad3dc8------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@lada496/storybook-%EF%BD%98nextauth-how-to-set-mock-auth-session-d1d3c0237e52?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/d1d3c0237e52</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[nextauth]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Mon, 02 Sep 2024 06:57:50 GMT</pubDate>
            <atom:updated>2024-09-02T06:59:19.805Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[[LeetCode] Visualization of Reverse Linked List]]></title>
            <link>https://medium.com/@lada496/leetcode-visualization-of-reverse-linked-list-b129fda49c2e?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/b129fda49c2e</guid>
            <category><![CDATA[leetcode]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Mon, 01 Jul 2024 04:51:38 GMT</pubDate>
            <atom:updated>2024-07-01T04:51:38.603Z</atom:updated>
            <content:encoded><![CDATA[<p>This is my memo when I solved <a href="https://leetcode.com/problems/reverse-linked-list/">206. Reverse Linked List</a>.</p><h3>What we want</h3><p>This is pretty simple. We want to re-order a provided linked list in the opposite direction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bVSRxRLU_RahUeT3j0j2pw.png" /></figure><h3>Strategy</h3><p>Go through each element and replace the value of next from the next element’s address with the previous element’s.</p><p>This requires us to handle two operations: 1) changing the value of next of each element and 2) tracking which element we’re updating and what element comes next.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YqkotOrISxFf9lrgLwU4_Q.png" /><figcaption>what we want to do in each round</figcaption></figure><h3>Code</h3><p>I think there are two tricky things when it comes to coding: 1) storing the next element to modify before updating curr.next, and 2) returning prev instead of curr as we update curr at the last of the while loop.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*THzyPjtfte1ME1-aVu6ljw.png" /><figcaption>the last round of the while loop</figcaption></figure><pre>/**<br> * Definition for singly-linked list.<br> * class ListNode {<br> *     val: number<br> *     next: ListNode | null<br> *     constructor(val?: number, next?: ListNode | null) {<br> *         this.val = (val===undefined ? 0 : val)<br> *         this.next = (next===undefined ? null : next)<br> *     }<br> * }<br> */<br><br>function reverseList(head: ListNode | null): ListNode | null {<br>    let [prev, curr] = [null, head]<br>    while(curr){<br>      const next = curr.next<br>      curr.next = prev<br>      prev = curr<br>      curr = next<br>    }<br>    return prev<br>    <br>};</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b129fda49c2e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[LeetCode] Concatenation of Array with Modular Arithmetic]]></title>
            <link>https://medium.com/@lada496/leetcode-concatenation-of-array-with-modular-arithmetic-a944bfc0cecf?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/a944bfc0cecf</guid>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Sat, 04 May 2024 04:47:59 GMT</pubDate>
            <atom:updated>2024-05-04T06:05:45.041Z</atom:updated>
            <content:encoded><![CDATA[<p>This is a memo of when I solved <a href="https://leetcode.com/problems/concatenation-of-array/">1929. Concatenation of Array</a>.</p><h3>Question</h3><p>You&#39;re given an array, nums, of arbitrary length. Your task is to return a new array, ans, that is twice as long as nums. The new array, ans, should satisfy the following conditions: ans[i] == nums[i] and ans[i + n] == nums[i], where 0 ≤ i &lt; n.</p><h3>Modular Arithmetic</h3><p>Modular arithmetic is a mathematical system that operates on integers by focusing on the remainder. The expression, x mod N, asks for the remainder of x when divided by N. For example, 13 mod 5 results in 3, because 3 is the remainder when 13 is divided by 3. a ≡ b (mod N) means that they share the same remainder when divided by N — for instance, 17 ≡ 8 (mod 3). In other words, modular arithmetic is a system that groups integers with their reminders.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qpZVI5_iXUnOIv3P-RsCYg.png" /><figcaption>an image of i mod 3 where i is an integers</figcaption></figure><h3>Solution Approach</h3><p>Let’s say the nums = [1, 2, 3]. The ans should be [1, 2, 3, 1, 2, 3] = [nums[0], nums[1], nums[2], nums[0], nums[1], nums[2]]. Therefore in general, we want to get an array of [nums[0], nums[1],,,, nums[nums.lenght-1], nums[0], nums[1],,,, nums[nums.lenght-1]].</p><p>Here is the time to employ modular. Let’s set i as an arbitral index of nums, N as the length of nums, and idx as an arbitral index of ans. Then we can get idx with i mod N. With the example above, 0 mod 3 = 3 mod 3 = 0, 1 mod 3 = 4 mod 3 = 1, 2 mod 3 = 5 mod 3 = 2.</p><h3>Implementation</h3><p>% is the operator that gets reminders in JavaScript.</p><pre>/**<br> * @param {number[]} nums<br> * @return {number[]}<br> */<br>var getConcatenation = function(nums) {<br>    let ans = []<br>    for(let i = 0; i &lt; nums.length * 2 ; i ++){<br>        const idx = i % nums.length // i mod nums.length<br>        ans.push(nums[idx])<br>    }<br>    return ans<br>};</pre><h3>Generalization</h3><p>What I like about the solution most is that it’s easy to generalize the number of concatenations. The question asks to repeat two times, but we can easily modify the code to repeat any number of times you want.</p><pre>/**<br> * @param {number[]} nums<br> * @param {number} x // the number of repetition<br> * @return {number[]}<br> */<br>var getConcatenation = function(nums, x) {<br>    let ans = []<br>    for(let i = 0; i &lt; nums.length * x; i ++){<br>        const idx = i % nums.length // i mod nums.length<br>        ans.push(nums[idx])<br>    }<br>    return ans<br>};</pre><p>⚠️ This is not a recommended answer, but I just wanted to say there is a way to utilize Math. You can find a model answer here.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F68isPRHgcFQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D68isPRHgcFQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F68isPRHgcFQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/fc3bdb66ba0c913b4cdac19dfed9e7c8/href">https://medium.com/media/fc3bdb66ba0c913b4cdac19dfed9e7c8/href</a></iframe><h3>Ref</h3><p><a href="https://brilliant.org/wiki/modular-arithmetic/">Modular Arithmetic | Brilliant Math &amp; Science Wiki</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a944bfc0cecf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exploring “Data Fetching with React Server Components” with Next.js]]></title>
            <link>https://towardsdev.com/exploring-data-fetching-with-react-server-components-with-next-js-54c96f77ea99?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/54c96f77ea99</guid>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[server-components]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Fri, 26 Apr 2024 06:41:42 GMT</pubDate>
            <atom:updated>2024-04-26T11:19:09.054Z</atom:updated>
            <content:encoded><![CDATA[<p>This is a brief takeaway of what I learned in this YouTube video titled “Data Fetching with Server Components.” I also tried Next.js to see what features we already have.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FTQQPAU21ZUw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DTQQPAU21ZUw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FTQQPAU21ZUw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ed64e383270c978f27cfe40edd8849b/href">https://medium.com/media/1ed64e383270c978f27cfe40edd8849b/href</a></iframe><p>· <a href="#65cf">Motivation</a><br> ∘ <a href="#6c4d">Issue</a><br> ∘ <a href="#715c">React Team’s Solution: Put data fetching logic on the server</a><br>· <a href="#0600">Server Side Rendering vs React Server Components</a><br> ∘ <a href="#2386">Server Side Rendering (SSR)</a><br> ∘ <a href="#7894">React Server Components</a><br>· <a href="#99e3">Server Component Features</a><br> ∘ <a href="#00c1">Zero Effect on the Bundle Size</a><br> ∘ <a href="#0299">Direct Access to the Backend Resources</a><br> ∘ <a href="#d788">Automatic Code Splitting</a><br> ∘ <a href="#b56f">Server Components require users’ decision</a><br> ∘ <a href="#d8cd">Server Components provide modern UX with a server-driven mental model</a><br>· <a href="#b131">Ref</a></p><h3>Motivation</h3><h4>Issue</h4><p>The React team wants to create apps with good user experience, cheap maintenance, and fast performance co-existing.</p><p>In general, having two of them in one project is comparatively more straightforward, but having all of them is pretty challenging.</p><p><strong>Example: Good user experience and fast performance</strong></p><p>With the code snippet, the app can render all components simultaneously and doesn’t suffer from the request waterfall, as it gets all data in one request. However, this code sacrifices the cheap maintenance because each component&#39;s API responses are coupled.</p><pre>function ArtistPage({artistId}){<br>const stuff = fetchAllTheStuffJustInCase()<br> return (<br>  &lt;ArtistDetails artistId={artistId} details={stuff.details} /&gt;<br>   &lt;TopTracks artistId={artistId} details={stuff.topTracks} /&gt;<br>   &lt;Discography artistId={artistId} details={stuff.discography} /&gt;<br>  &lt;/ArtistDetails&gt;<br> )<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=4m12s</pre><p>🗒️ This code reminds me of the Easier to Change (ETC) principle provided in <a href="https://www.amazon.ca/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052/ref=sr_1_1?dib=eyJ2IjoiMSJ9.84Xun4zePRzxcYJXHbNXB7dVm4lTzy9-7zrFUNgNQC8ZHty2sHX0n1IsAHY91IBc1bdPT4gNcMDDvpCGNBFy8ACvEMWwwO2NpQIt3nNCUaePhJevHoblIHrPC0wdt93H8FBHZG831b7lpaU1TAUTkpo5ZIv3B6QdxWZ4cK9NtdKEvbDE8TQuUllAA3XORSC3XChN_6O6ctCfYW6CORYlIidUMhzEe_ef0BFZ9ambMqTHSmRv5GTC_JsVce7g2gR7cSTnlk8-DWYf5Qhry9nSpj6byyhQhG0Miq_DXQmn6zs.Kat3fEXI70AhmdZguQ2hKqnCeNj1jjMHU06GPtLRw9I&amp;dib_tag=se&amp;hvadid=667095410527&amp;hvdev=c&amp;hvlocphy=9001551&amp;hvnetw=g&amp;hvqmt=e&amp;hvrand=18375279749113656674&amp;hvtargid=kwd-302199567278&amp;hydadcr=23310_13656858&amp;keywords=the+pragmatic+programmer&amp;qid=1712210601&amp;sr=8-1"><em>The Pragmatic Programmer</em></a>. According to the book, “Good design is easier to change than bad design.” It also says, “Decoupled code is easier to change.”</p><p>The code below can reduce the maintenance cost but causes a so-called <a href="https://tanstack.com/query/latest/docs/framework/react/guides/request-waterfalls#what-is-a-request-waterfall">request waterfall</a>, sacrificing the performance speed. In addition, the app no longer renders all components simultaneously, and now they all depend on each request order.</p><pre>// Ideal way<br>function ArtistPage({artistId}){<br> return (<br>  &lt;ArtistDetails artistId={artistId} /&gt;<br>   &lt;TopTracks artistId={artistId} /&gt;<br>   &lt;Discography artistId={artistId} /&gt;<br>  &lt;/ArtistDetails&gt;<br> )<br>}<br><br>function ArtistDetails({artistId}) {<br> const details = fetchDetails(artistId)<br> // ...<br>}<br><br>function TopTracks({artistId}) {<br> const topTracks = fetchTocpTracks(artistId)<br> // ...<br>}<br><br>function Discography({artistId}) {<br> const discography = fetchDiscograhy(artistId)<br> // ...<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=5m20s</pre><p>🗒 I like this part because I can sense the strong eagerness to break through what we call impossible.</p><h4>React Team’s Solution: Put data fetching logic on the server</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZuI-9uE5g6HKDvkjDvuw0w.png" /><figcaption>Before</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b6aMoNtgfDWtrp6_IbgF-g.png" /><figcaption>After</figcaption></figure><h3>Server Side Rendering vs React Server Components</h3><h4>Server Side Rendering (SSR)</h4><p>SSR is a technique that serves an initial HTML when the first page loads. Once the first HTML is loaded, it is required to download/parse/execute Client Components.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IY2oJ3sJRv7JJldnrDomVg.png" /><figcaption>A very simplified SSR image</figcaption></figure><h4>React Server Components</h4><p>React Server Components are not interactive with the client side. Client Components always take responsibility for interacting with users and trigger re-fetch Server Components trees corresponding to the user’s actions. Notably, the client-side state is preserved when the re-fetch. We can do this with Server Components because Server Components don’t render to HTML, but they render into a special format.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zCAyYNG8IP61MmewTywwOA.png" /></figure><p>Here is an example of where the client states are preserved when the re-fetch with Next.js. The search input appears only when the search input state is true, and the to-do list is filtered by the filter query controlled on the server side.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RUpSTMWbf24kwwsrBRldWA.gif" /></figure><p>cf) Here is how Next.js explains the interaction between Server Components and Client Components. Next.js calls the special format React Server Component Payload.</p><p><a href="https://nextjs.org/learn/react-foundations/server-and-client-components">React Foundations: Server and Client Components | Next.js</a></p><h3>Server Component Features</h3><h4>Zero Effect on the Bundle Size</h4><p>We can reduce dependencies downloaded to the client by moving some heavy dependencies components to the server.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1vLVf4y3BW7uk1hk5PYLUg.png" /></figure><p>⚠️ Not exactly HTML files (as Server Components render into a special format), but I mention only HTML here for the sake of ease.</p><h4>Direct Access to the Backend Resources</h4><p>Because Server Components are rendered on the server side, they can access the server-side resources directly.</p><pre>// Example 1<br><br>import { resolve, join } from &#39;path&#39;;<br>import { readdir, readFile } from &#39;react-fs&#39;;<br>import marked from &#39;marked&#39;;<br><br>const folder = resolve(__dirname + &#39;/../posts&#39;);<br><br>function Blog() {<br> return readdir(folder).map(name =&gt; <br>  &lt;article key={name}&gt;<br>   {/* Access the file system directly without creating any API */}<br>   {marked(readFile(join(folder, file), &#39;utf8&#39;))} <br>  &lt;/articke&gt;<br> );<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=37m57s</pre><pre>// Example 2<br><br>import marked from &#39;marked&#39;;<br>import { db } from &#39;./db&#39;;<br><br>function Blog() {<br> return db.posts.getAll().map(post =&gt; <br>  &lt;article key={post.id}&gt;<br>   {marked(post.html)}<br>  &lt;/article&gt;<br> )<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=38m05s</pre><h4>Automatic Code Splitting</h4><p>Server components allow for the loading of only the required code. This means that server components are not downloaded to the client, and even client components that are not being used do not need to be downloaded.</p><pre>// Example<br><br>import EditToobar from &#39;./EditToolbar.client&#39;;<br><br>function Comment({ comment, currentUser }) {<br> const canEdit = (<br>  currentUser.isAdmin ||<br>  currentUser.id === comment.author.id<br> );<br> return (<br>  &lt;Box&gt;<br>  {/* EditToonar is downloaded only when canEdit === true */}<br>   {canEdit &amp;&amp; &lt;EditToolbar /&gt;}<br>   &lt;p&gt;{comment.text}&lt;/p&gt;<br>  &lt;/Box&gt;<br> )<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=41m25s</pre><p>This is questionable with Next.js, as I found client components not rendered in the initial render when I inspected the source after running npm run build.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4LXayrkefemDErvyrH-V9g.gif" /><figcaption>Demo of experimental code</figcaption></figure><h4>Server Components require users’ decision</h4><p>Server Components let you decide the Client and Server Components tradeoff for every concrete use case.</p><p><a href="https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#when-to-use-server-and-client-components">Rendering: Composition Patterns | Next.js</a></p><p>🗒️ I think this is a double-edged sword feature as we have to understand the ins and outs of React, including both Server Components and Client Components (and Shared Components), to decide which to use in each case. In other words, it all depends on developers to make the most of the server components or to make them waste treasures.</p><h4>Server Components provide modern UX with a server-driven mental model</h4><p>Server Components enable developers to create modern and app-like user interfaces in an old-school way.</p><pre>// Example<br><br>import SearchInput from &#39;./SearchInput.client&#39;;<br><br>function SearchResults({searchText}) {<br> const results = fetch(&#39;/search?q&#39; + searchText).json();<br> return (<br>  &lt;&gt;<br>   {/*This component triggers re-fetch of the server tree*/}<br>   &lt;SearchInput /&gt; <br>   &lt;ul&gt;<br>    {results.map(result =&gt; <br>     &lt;li key={result.id}&gt;{result.text}&lt;/li&gt;<br>    )}<br>   &lt;/ul&gt;<br>  &lt;/&gt;<br> )<br>}<br><br>// https://youtu.be/TQQPAU21ZUw&amp;t=44m45s</pre><h3>Ref</h3><ul><li><a href="https://react.dev/blog/2020/12/21/data-fetching-with-react-server-components">Introducing Zero-Bundle-Size React Server Components - React</a></li><li><a href="https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md#rfc-react-server-components">rfcs/text/0188-server-components.md at main · reactjs/rfcs</a></li></ul><p>The whole demo code is available <a href="https://github.com/Lada496/next-experiment">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=54c96f77ea99" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/exploring-data-fetching-with-react-server-components-with-next-js-54c96f77ea99">Exploring “Data Fetching with React Server Components” with Next.js</a> was originally published in <a href="https://towardsdev.com">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[tRPC 102: Subscription/Web Socket]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@lada496/trpc-102-subscription-web-socket-d81b8962a010?source=rss-26c837ad3dc8------2"><img src="https://cdn-images-1.medium.com/max/600/1*nqE96GDpMlWcQQAG_6xYnA.gif" width="600"></a></p><p class="medium-feed-snippet">This is my memo when I implemented a subscription with tRPC along with the official documents.</p><p class="medium-feed-link"><a href="https://medium.com/@lada496/trpc-102-subscription-web-socket-d81b8962a010?source=rss-26c837ad3dc8------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@lada496/trpc-102-subscription-web-socket-d81b8962a010?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/d81b8962a010</guid>
            <category><![CDATA[subscription]]></category>
            <category><![CDATA[websocket]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Wed, 12 Jul 2023 04:03:47 GMT</pubDate>
            <atom:updated>2023-07-12T04:03:47.902Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[tRPC 101: Concepts and some code experiments with create T3 app]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://towardsdev.com/trpc-101-concepts-and-some-code-experiments-with-create-t3-app-b4af41cad587?source=rss-26c837ad3dc8------2"><img src="https://cdn-images-1.medium.com/max/600/1*Ny8CiedRod_2geuiTWKQFw.gif" width="600"></a></p><p class="medium-feed-snippet">In this article, I will share what I&#x2019;ve learned about tRPC with an example app built with create T3 app.</p><p class="medium-feed-link"><a href="https://towardsdev.com/trpc-101-concepts-and-some-code-experiments-with-create-t3-app-b4af41cad587?source=rss-26c837ad3dc8------2">Continue reading on Towards Dev »</a></p></div>]]></description>
            <link>https://towardsdev.com/trpc-101-concepts-and-some-code-experiments-with-create-t3-app-b4af41cad587?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/b4af41cad587</guid>
            <category><![CDATA[trpc]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Tue, 11 Jul 2023 19:29:51 GMT</pubDate>
            <atom:updated>2023-07-12T15:06:40.241Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[PostgreSQL 101: From what’s database to basic SQL queries]]></title>
            <link>https://towardsdev.com/postgresql-101-from-whats-database-to-basic-sql-queries-1aea5caed904?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/1aea5caed904</guid>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Tue, 11 Jul 2023 19:24:37 GMT</pubDate>
            <atom:updated>2023-07-13T12:08:31.138Z</atom:updated>
            <content:encoded><![CDATA[<p>In this article, I will share what I’ve learned about basic knowledge of database and queries with PostgreSQL examples including one of installation processes.</p><p>Contents:</p><ul><li><a href="#ead0">What is database?</a></li><li><a href="#df14">Work with PostgreSQL</a><br><a href="#9df2">1. Install PostgreSQL</a><br><a href="#336d">2. Create Database</a><br><a href="#3fdc">3. Create tables</a><br><a href="#e95e">4. Insert into: How to insert values</a><br><a href="#c237">5. Select: How to get table values</a><br><a href="#5d27">6. Alter: How to add another column to an existing table</a><br><a href="#9952">7. Update: How to update existing row values</a><br><a href="#c555">8. Join: How to connect tables</a><br><a href="#7dd0">9. Delete : How to delete rows</a><br><a href="#0814">10. Drop table: How to delete tables</a></li></ul><h3>What is database?</h3><p>A database is an organized collection of structured data stored electronically, typically managed by a DBMS, forming a database system (<a href="https://www.oracle.com/ca-en/database/what-is-database/#:~:text=A%20database%20typically%20requires%20a,information%20is%20organized%20and%20optimized.">What is database software?</a>).</p><p>There are two main DBMS: Relational databases and NoSQL/Non relational database. I will focus more on relational databases in this article as PostgreSQL is a relational database.</p><p><strong>Relational database</strong> is consist of tables with columns and rows. Columns hold specific data types and fields store attribute values. Rows represent a collection of related values. Rows can be so called a primary key, an unique identifier and relationships between rows in different tables are established using foreign keys (<a href="https://aws.amazon.com/relational-database/">What is a Relational Database?</a>).</p><figure><img alt="image of relational database" src="https://cdn-images-1.medium.com/max/1024/1*EiCqi4vxa_NzqT1qY9pXEQ.png" /></figure><p>SQL allows us to communicate with relational databases.</p><figure><img alt="image of sql" src="https://cdn-images-1.medium.com/max/1024/1*svIr5vBEsIZ3Z46mD2lCvg.png" /></figure><p><strong>NoSQL/Non relational databases </strong>are databases which store data in a different way from relational databases. There are variety of ways to store data such as document, key-value, wide-column, and graph (<a href="https://www.mongodb.com/nosql-explained#:~:text=NoSQL%20databases%20(aka%20%22not%20only,wide%2Dcolumn%2C%20and%20graph.">What is NoSQL?</a>).</p><h3>Work with PostgreSQL</h3><h4>1. Install PostgreSQL</h4><p>Here is a way to download PostgreSQL on MacOS with homebrew.</p><p><strong>Preparation</strong></p><p>0. (Optional) Download GUI for PostgreSQL: I chose pgAdmin 4 simply because it’s free (<a href="https://www.slant.co/topics/59/~best-mac-os-x-guis-for-postgresql">What are the best Mac OS X GUIs for PostgreSQL?</a>)</p><ol><li>make sure homebrew is updated: brew update</li><li>confirm that everything is working fine: brew doctor</li></ol><p><strong>Installation</strong></p><ol><li>brew install postgresql <br>Check the command to start postgresql service. It was brew services start postgresql@14 in my case.</li></ol><h4>2. Create Database</h4><ol><li>Start the service: brew services start postgresql@14 <br>You will see a success message like Successfully started ‘postgresql@14’ (label: homebrew.mxcl.postgresql@14)</li><li>Create a database: createdb ‘test’</li><li>(Optional for GUI) create an user: createuser testuser</li><li>(Optional for GUI) open pgAdmin4</li><li>(Optional for GUI) Click “Add New Server”</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oiRsbUL-ORJIBs97exZXVQ.png" /></figure><p>6. (Optional for GUI) Input the server name (e.g. localhost)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L7tEX2YJEqw8ADPnwCc_hQ.png" /></figure><p>7. (Optional for GUI) click connection tab</p><p>8. (Optional for GUI) Input database name, user name, and address</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sp60e91d5mC9EYTHsaQRKQ.png" /></figure><p>9 (Optional for GUI) You will see Explorer</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bJGDGH6SYhgTlWTq1MU2dw.png" /></figure><p>10. Connect to the database: psql &#39;test&#39; (and \q to exit)</p><h4>3. Create tables</h4><p>Make sure you’ve connected the target database before creating tables.</p><p>Syntax:</p><pre>CREATE TABLE table_name (column_1 datatype, ..., column_n datatype);<br><br># Example<br>CREATE TABLE users (name text, age smallint, birthday date);</pre><p>You can find various data types provided by PostgreSQL here.</p><p><a href="https://www.postgresql.org/docs/current/datatype.html">Chapter 8. Data Types</a></p><p>Then you will find the table with GUI, or you can check with \d command with Terminal.</p><pre># Command result<br> <br>List of relations<br> Schema | Name  | Type  |    Owner     <br>--------+-------+-------+--------------<br> public | users | table | ownername<br>(1 row)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xMPA7rbLPzMDyz3wlJN37Q.png" /><figcaption>tables in GUI</figcaption></figure><h4>4. Insert into: How to insert values</h4><p>Syntax:</p><pre>INSERT INTO table_name (column_1, ..., column_n) VALUES (value_1, ... value_n);<br><br># Example<br>INSERT INTO users (name, age, birthday) VALUES (&#39;Hermione&#39;, 10, &#39;1979-09-19&#39;);</pre><h4>5. Select: How to get table values</h4><p>Basic syntax:</p><pre>SELECT column_1, ..., column_n FROM table_name;<br><br># Example1<br>SELECT name, age, birthday FROM users;<br><br># Result1<br> name     | age |  birthday  <br>----------+-----+------------<br> Hermione |  10 | 1979-09-19<br><br># Example2<br>SELECT name FROM users;<br><br># Result2<br>   name   <br>----------<br> Hermione</pre><p>When you want to select all columns:</p><pre>SELECT * FROM table_name;<br><br># Example<br>SELECT * FROM users;<br><br># Result<br> name     | age |  birthday  <br>----------+-----+------------<br> Hermione |  10 | 1979-09-19</pre><p>You can find some conditional selections:</p><ul><li><a href="https://www.w3schools.com/sql/sql_where.asp">SQL WHERE Clause</a></li><li><a href="https://www.w3schools.com/sql/sql_orderby.asp">SQL ORDER BY Keyword</a></li></ul><p>Also we have some SQL functions:</p><p><a href="https://www.w3schools.com/sql/sql_count_avg_sum.asp">SQL COUNT(), AVG() and SUM() Functions</a></p><h4>6. Alter: How to add another column to an existing table</h4><p>Syntax:</p><pre>ALTER TABLE table_name ADD column_name datatype;<br><br># Example<br>ALTER TABLE users ADD house text;<br><br># Result<br>   name   | age |  birthday  | house <br>----------+-----+------------+-------<br> Hermione |  10 | 1997-09-19 | <br> Ron      |  10 | 1980-03-01 | </pre><h4>7. Update: How to update existing row values</h4><p>Syntax:</p><pre>UPDATE table_name SET column_name1 = column_value1 WHERE column_name2 = column_value2;<br><br>#Example<br>UPDATE users SET house = &#39;Gryffindor&#39; WHERE name = &#39;Hermione&#39;;<br><br># Result<br>   name   | age |  birthday  |   house    <br>----------+-----+------------+------------<br> Ron      |  10 | 1980-03-01 | <br> Hermione |  10 | 1997-09-19 | Gryffindor</pre><h4>8. Join: How to connect tables</h4><p>Syntax:</p><pre>SELECT * FROM table1_name JOIN table2_name ON table1_name.primary_key = table1_name.foreign_key</pre><p>Suppose we have tier table below and want to get users information with rank data:</p><pre>CREATE TABLE tier (id serial NOT NULL PRIMARY KEY, rank text, name text UNIQUE NOT NULL);<br><br>SELECT * FROM tier<br> id | rank |   name   <br>----+------+----------<br>  1 | s    | Hermione<br>  2 | s    | Ron<br>  3 | s    | Harry<br>  4 | a    | Draco</pre><p>Then the SQL query will be:</p><pre>SELECT name, age, birthday, house, rank FROM users JOIN tier ON users.name = tier.name;<br><br># Result<br>   name   | age |  birthday  |   house    | id | rank |   name   <br>----------+-----+------------+------------+----+------+----------<br> Hermione |  10 | 1997-09-19 | Gryffindor |  1 | s    | Hermione<br> Ron      |  10 | 1980-03-01 | Gryffindor |  2 | s    | Ron<br> Harry    |  10 | 1980-07-31 | Gryffindor |  3 | s    | Harry<br> Draco    |  10 | 1980-06-05 | Slytherin  |  4 | a    | Draco</pre><h4>9. Delete : How to delete rows</h4><p>Syntax:</p><pre>DELETE FROM table_name WHERE your conditoin;<br><br># Example<br>DELETE FROM users WHERE name=&#39;Voldemort&#39;;</pre><h4>10. Drop table: How to delete tables</h4><p>Syntax:</p><pre>DROP TABLE table_name;<br><br># Example<br>DROP TABLE users;</pre><p>That’s it! Thank you for reading :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1aea5caed904" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/postgresql-101-from-whats-database-to-basic-sql-queries-1aea5caed904">PostgreSQL 101: From what’s database to basic SQL queries</a> was originally published in <a href="https://towardsdev.com">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to setup Prisma with your local PostgreSQL]]></title>
            <link>https://medium.com/@lada496/how-to-setup-prisma-with-your-local-postgresql-a82407ff823e?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/a82407ff823e</guid>
            <category><![CDATA[prisma]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Tue, 11 Jul 2023 02:36:20 GMT</pubDate>
            <atom:updated>2024-09-01T06:15:31.003Z</atom:updated>
            <content:encoded><![CDATA[<p>This is my memo when I tried t3 app with PostgreSQL for the first time.</p><p>Pre-requirements: install postgresql<br>OS: macOS</p><ol><li>psql postgres to enter postgres</li><li>Create an user with CREATEDBpermission: CREATE ROLE &lt;username&gt; WITH LOGIN PASSWORD &#39;&lt;password&gt;&#39; CREATEDB;</li><li>go to your app’s root folder</li><li>make sure the provide is ‘postgresql’ at prisma/schema.prisma</li></ol><pre>datasource db {<br>    provider = &quot;postgresql&quot;<br>    url      = env(&quot;DATABASE_URL&quot;)<br>}</pre><p>5. Database url has the following structure: postgresql://username:password@localhost:5432/database-name <br>⚠️ If you don’t use the default port number, replace from 5432 to yours.</p><p>6. npx prisma migrate dev --name initial</p><p>Special thanks: <a href="https://www.codementor.io/@engineerapart/getting-started-with-postgresql-on-mac-osx-are8jcopb">https://www.codementor.io/@engineerapart/getting-started-with-postgresql-on-mac-osx-are8jcopb</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a82407ff823e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Updated my Next.js project to v13 Appendix: Troubleshooting]]></title>
            <link>https://medium.com/@lada496/updated-my-next-js-project-to-v13-appendix-troubleshooting-26b9492c227?source=rss-26c837ad3dc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/26b9492c227</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[nextjs]]></category>
            <dc:creator><![CDATA[Lada496]]></dc:creator>
            <pubDate>Sun, 28 May 2023 23:23:02 GMT</pubDate>
            <atom:updated>2023-05-28T23:41:53.186Z</atom:updated>
            <content:encoded><![CDATA[<p>This is a series of my memo from when I migrated Next.js v13 into my project with the article <a href="https://nextjs.org/docs/pages/building-your-application/upgrading/app-router-migration#migrating-_documentjs-and-_appjs">From Pages to App</a>. I also updated other packages’ versions. I decided to put the list of problems I encountered while the development process and also how I fixed them.</p><p><a href="https://medium.com/@lada496/updated-my-next-js-project-to-v13-part1-migrated-app-router-27c3ce172bba">Part1: Migrated app router from page router</a></p><p><a href="https://medium.com/@lada496/updated-my-next-js-project-to-v13-part2-hooks-for-app-router-38a82a8e5b0">Part2: Migrated router API</a></p><p><a href="https://medium.com/@lada496/updated-my-next-js-project-to-v13-part2-link-use-client-3f5e17d12b8f">Part3: Applied some other Next.js v13 updates</a></p><p><a href="https://medium.com/@lada496/updated-nextauth-from-v3-to-v4-4210f2b994e3">Optional: Updated NextAuth from v3 to v4</a></p><p><a href="https://medium.com/@lada496/optimistic-updates-with-rtk-query-4770698de6c1">Optional: Updated Redux from classical Redux to Redux Toolkit Query</a></p><h3>Vague error messages</h3><h4><strong>Error: React Context is unavailable in Server Components</strong></h4><p>You have to put &quot;use client&quot; to use &quot;<a href="https://next-auth.js.org/getting-started/client#sessionprovider">SessionProvider</a>&quot; provided by nextAuth because it uses React Context behind the scene.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BwwbLsGneX9h6i6P0DHepA.png" /><figcaption>error message from SessionProvider</figcaption></figure><p>I read some articles setting up NextAuth with Next.js and found that the current common practice is creating a provider as a client-side component and wrapping with it at app/layout.js rather than using SessionProvider directly. This approach applies to other providers which also require use client.</p><ul><li><a href="https://codevoweb.com/setup-and-use-nextauth-in-nextjs-13-app-directory/">Setup and Use NextAuth.js in Next.js 13 App Directory 2023</a></li><li><a href="https://blog.bitsrc.io/adding-nextauth-to-nextjs-13-and-authenticating-with-github-40539ca6a81c">Add NextAuth to NextJS 13 and Authenticate with GitHub</a></li></ul><h4>TypeError: (0 , _react.createContext) is not a function</h4><p>This is another pattern that you have to put &quot;use client”. If you see this message, most likely you’re using redux hooks/utils in server components. One tricky thing is that Redux doesn’t specify what file causes this error.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RQk_vkY0xg8vrth2vAhy1g.png" /><figcaption>error message from Redux</figcaption></figure><h4><strong>TypeError: Cannot read properties of undefined (reading ‘prototype’)</strong></h4><p>This error came from semantic-ui-react and also told me to put &quot;use client&quot;. So far, you have to put &quot;use client&quot; at all files which include semantic-ui-react components. Alternatively, you can create client components for each semantic-ui-react component. But I haven’t applied this approach yet.</p><pre>&quot;use client&quot;<br>import { Grid as SemanticGrid } from &quot;semantic-ui-react&quot;;<br><br>const Grid = (props) =&gt; {<br>  return &lt;SemanticGrid {...props}&gt;{props.children}&lt;/SemanticGrid&gt;<br>}</pre><h4><strong>TypeError: Cannot read properties of undefined (reading ‘select’)</strong></h4><p>This is more likely because your first argument of updateQueryData (endpoint name) is incorrect. In the case below, it should be getCartItems to match the actual query I defined.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MBbOs_qc3s1CibUE21QFFw.png" /><figcaption>error message from redux</figcaption></figure><p><a href="https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced#implementing-optimistic-updates">Redux Essentials, Part 8: RTK Query Advanced Patterns | Redux</a></p><h4><strong>Error: [Immer] The first or second argument to `produce` must be a function</strong></h4><p>I got this error because I forgot to put the second argument for updateQueryData (cache key arguments).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*86JL9qDiufDemlQYlVvNDw.png" /><figcaption>error message from redux</figcaption></figure><h3>Different CSS files loading b/w production and dev</h3><p>After deploying on vercel, I found there is a wired padding provided by semantic ui css file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y46Bne3tBK2AhS20ENDObw.png" /></figure><p>Here is how Next.js optimize css files during the build process. My global.css file cannot always override semantic ui stylings.</p><blockquote>When building for production with <em>next build</em>, CSS files will be bundled into fewer minified <em>.css</em> files to reduce the number of network requests needed to retrieve styles.</blockquote><p><a href="https://nextjs.org/docs/app/building-your-application/styling/css-modules#additional-features">CSS Modules</a></p><p>The quick and dirty way is put !important for those stylings you want to override stylings. But I think a better way in my case is to add stylings with styled-components.</p><h3>No redux-next-wapper for Next.js 13 so far</h3><p>Because of it, I decided to use rest api more often than before to keep most of data on the server side rather than saving it in local storage.</p><p><a href="https://github.com/kirill-konshin/next-redux-wrapper/issues/494">Usage with Next.js 13? · Issue #494 · kirill-konshin/next-redux-wrapper</a></p><p>I tried Optimistic updates for a better user experience.</p><p><a href="https://medium.com/@lada496/optimistic-updates-with-rtk-query-4770698de6c1">Optimistic Updates with RTK Query</a></p><p>That’s it! It was more difficult for me to catch/handle errors than usual because most of libraries still assume React ecosystem. Hope it helps someone as well. Please let me know if you have/find any better solution. Thank you for reading :)</p><p><a href="https://github.com/Lada496/benlya">code</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26b9492c227" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>