<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KazooTTT</title>
    <description>The latest articles on DEV Community by KazooTTT (@kazoottt).</description>
    <link>https://dev.to/kazoottt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F875237%2F92e50b17-c00e-4e7d-aea9-ac6c2c558487.jpg</url>
      <title>DEV Community: KazooTTT</title>
      <link>https://dev.to/kazoottt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kazoottt"/>
    <language>en</language>
    <item>
      <title>Talking About Things I Dislike About Atlas</title>
      <dc:creator>KazooTTT</dc:creator>
      <pubDate>Sat, 25 Oct 2025 14:22:00 +0000</pubDate>
      <link>https://dev.to/kazoottt/talking-about-things-i-dislike-about-atlas-9hp</link>
      <guid>https://dev.to/kazoottt/talking-about-things-i-dislike-about-atlas-9hp</guid>
      <description>&lt;p&gt;On October 21, 2025, OpenAI released a new product: Atlas, which flooded social media timelines.&lt;/p&gt;

&lt;p&gt;Many people have already praised it or created tutorials on how to use it. There's no denying that it has some good aspects, but this article briefly lists the points that I find uncomfortable or dislike.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Can only import configurations from Safari and Google Chrome
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-893df7fe591f4f312a1729140447b0d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-893df7fe591f4f312a1729140447b0d6.png" alt="IMG-893DF7FE591F4F312A1729140447B0D6" width="792" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Does not support other browsers, such as Edge, Arc, Firefox...&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The menu interaction in the top-right corner is a bit abstract
&lt;/h2&gt;

&lt;p&gt;The main menu trigger is click, but the submenu trigger is hover, and clicking on a submenu item closes the entire menu. This easily leads to users making ineffective clicks, wasting time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-beec0c69e868754ecab29cb6130145cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-beec0c69e868754ecab29cb6130145cb.png" alt="IMG-BEEC0C69E868754ECAB29CB6130145CB" width="650" height="385"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. No way to batch pin browser extensions, have to activate them one by one
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-d22d92ebf4a2461f44708ff10ad80781.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-d22d92ebf4a2461f44708ff10ad80781.png" alt="IMG-D22D92EBF4A2461F44708FF10AD80781" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Not allowed to modify the position of devtools
&lt;/h2&gt;

&lt;p&gt;This is Atlas&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-b952eed7fb495fb3a711449bcfa209f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-b952eed7fb495fb3a711449bcfa209f5.png" alt="IMG-B952EED7FB495FB3A711449BCFA209F5" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is other browsers&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-be5c7ab492b226846455cfbf03384d19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-be5c7ab492b226846455cfbf03384d19.png" alt="IMG-BE5C7AB492B226846455CFBF03384D19" width="590" height="284"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Rewrote the right-click context menu
&lt;/h2&gt;

&lt;p&gt;This causes some browser extensions to be unusable (such as Wucai, Raindrop's highlighting feature)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-4f73c202390f0bcd8d7aae989134d258.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-4f73c202390f0bcd8d7aae989134d258.png" alt="IMG-4F73C202390F0BCD8D7AAE989134D258" width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Sometimes when activating browser extensions, cannot open popup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-c4699b26075b5a90d45df8a4b036f0bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-c4699b26075b5a90d45df8a4b036f0bd.png" alt="IMG-C4699B26075B5A90D45DF8A4B036F0BD" width="568" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, my 1Password can never open, and cannot paste passwords, making it unusable&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Cannot set browser configurations or use debugging features
&lt;/h2&gt;

&lt;p&gt;For example, the WebGL engine, and cannot enable mobile debugging pages&lt;/p&gt;

&lt;p&gt;Sometimes you need to access &lt;code&gt;chrome://flags&lt;/code&gt; like in Google Chrome and set "Choose ANGLE graphics backend" to OpenGL.&lt;/p&gt;

&lt;p&gt;Or access &lt;code&gt;chrome://inspect#devices&lt;/code&gt; to debug devices&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-349fd7315f24940052c8bfb294a96e22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-349fd7315f24940052c8bfb294a96e22.png" alt="IMG-349FD7315F24940052C8BFB294A96E22" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But in Atlas: &lt;code&gt;atlas://settings&lt;/code&gt;, &lt;code&gt;atlas://flags&lt;/code&gt;, &lt;code&gt;atlas://inspect#devices&lt;/code&gt; are all inaccessible&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-4f3506d9e589a91c18e757b22550cfe5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251022-4f3506d9e589a91c18e757b22550cfe5.png" alt="IMG-4F3506D9E589A91C18E757B22550CFE5" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Overall, while it has made innovations in AI integration and interaction, this product is too closed off, even removing some common features and configurations of browsers themselves.&lt;/p&gt;

&lt;p&gt;If you rely heavily on browser extensions to enhance your browsing experience, or if you're a developer, I don't recommend using Atlas as your main browser.&lt;/p&gt;

&lt;p&gt;If you're not in the above situations and want to use ChatGPT for page information processing and learning (such as reading documentation, explaining the meaning of selected content), or want to try the agent mode (doing some automated operations), then you can give Atlas a try.&lt;/p&gt;

</description>
      <category>openai</category>
      <category>chatgpt</category>
      <category>browser</category>
    </item>
    <item>
      <title>Recommend some VS Code extensions for frontend development</title>
      <dc:creator>KazooTTT</dc:creator>
      <pubDate>Tue, 21 Oct 2025 06:01:38 +0000</pubDate>
      <link>https://dev.to/kazoottt/recommend-some-vs-code-extensions-for-frontend-development-27g7</link>
      <guid>https://dev.to/kazoottt/recommend-some-vs-code-extensions-for-frontend-development-27g7</guid>
      <description>&lt;p&gt;I won't recommend language-related extensions since most people already have them installed.&lt;br&gt;&lt;br&gt;
These extensions work with vscode, cursor, trae, windsurf and other editors.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. &lt;a href="https://marketplace.visualstudio.com/items?itemName=antfu.file-nesting" rel="noopener noreferrer"&gt;File Nesting Updater - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Automatically syncs and updates file nesting configurations maintained by the author, making the file explorer cleaner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-cd5447894897e788e70684ff1dba8c61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-cd5447894897e788e70684ff1dba8c61.png" alt="Pasted image 20251020141840" width="694" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2. &lt;a href="https://marketplace.visualstudio.com/items?itemName=ChakrounAnas.turbo-console-log" rel="noopener noreferrer"&gt;Turbo Console Log - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Quickly generates meaningful logs (showing file line numbers, function names, variable names) and allows one-click deletion of added logs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-8be5636a37f380c6c86b708c0c2bd3ad.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-8be5636a37f380c6c86b708c0c2bd3ad.gif" alt="IMG-8BE5636A37F380C6C86B708C0C2BD3AD" width="600" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3. &lt;a href="https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors" rel="noopener noreferrer"&gt;Pretty TypeScript Errors - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Makes TypeScript errors more readable and allows direct navigation to TypeScript documentation for better error understanding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-b938b0f373c7753bd8d87ddbc89341b3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-b938b0f373c7753bd8d87ddbc89341b3.png" alt="IMG-B938B0F373C7753BD8D87DDBC89341B3" width="765" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4. &lt;a href="https://marketplace.visualstudio.com/items?itemName=MariusAlchimavicius.json-to-ts" rel="noopener noreferrer"&gt;JSON to TS - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Quickly converts JSON to TypeScript types.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-53a8eb8fb52698d7a25c9a5d0437720b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-53a8eb8fb52698d7a25c9a5d0437720b.gif" width="972" height="715"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.5. &lt;a href="https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens" rel="noopener noreferrer"&gt;Error Lens - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Displays errors and warnings directly inline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-509ca7645b9a6adca902128f8a22c777.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-509ca7645b9a6adca902128f8a22c777.png" alt="IMG-509CA7645B9A6ADCA902128F8A22C777" width="800" height="162"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  1.6. &lt;a href="https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments" rel="noopener noreferrer"&gt;Better Comments - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Displays different styles for different types of comments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-f5711d684b9a167e973583f479f4e5cf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-f5711d684b9a167e973583f479f4e5cf.png" alt="IMG-F5711D684B9A167E973583F479F4E5CF" width="459" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.7. &lt;a href="https://marketplace.visualstudio.com/items?itemName=liamhammett.inline-parameters" rel="noopener noreferrer"&gt;Inline Parameters for VSCode&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Shows parameter names as inline hints at function call sites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-79678d80033b96fb92a3b6b9c4ee7ff1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-79678d80033b96fb92a3b6b9c4ee7ff1.gif" width="600" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-8f7fdfc33c5e909ebac0a635e444b553.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-8f7fdfc33c5e909ebac0a635e444b553.png" alt="IMG-8F7FDFC33C5E909EBAC0A635E444B553" width="539" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Themes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1. Symbols Icons
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=miguelsolorio.symbols" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=miguelsolorio.symbols&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-6a98552cab5b5e5f85c1fa4edeafb900.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-6a98552cab5b5e5f85c1fa4edeafb900.png" alt="IMG-6A98552CAB5B5E5F85C1FA4EDEAFB900" width="304" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-b02157769e89b2ed3fc6c805d4520b47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-b02157769e89b2ed3fc6c805d4520b47.png" alt="IMG-B02157769E89B2ED3FC6C805D4520B47" width="655" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2. &lt;a href="https://marketplace.visualstudio.com/items?itemName=illixion.vscode-vibrancy-continued" rel="noopener noreferrer"&gt;Vibrancy Continued - Visual Studio Marketplace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;May impact performance and report editor corruption warnings. Use with caution (only for experimentation).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251021-901a2a5bdd5cba21a441c499cdab2c13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251021-901a2a5bdd5cba21a441c499cdab2c13.png" alt="IMG-901A2A5BDD5CBA21A441C499CDAB2C13" width="800" height="502"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Others
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1. &lt;a href="https://wakatime.com/" rel="noopener noreferrer"&gt;WakaTime - Dashboards for developers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Tracks coding time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-3c2f5219c3f196f6e60542674c31de29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-3c2f5219c3f196f6e60542674c31de29.png" alt="IMG-3C2F5219C3F196F6E60542674C31DE29" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. How to download when non-VSCode editors can't access the VSCode marketplace
&lt;/h2&gt;

&lt;p&gt;VSCode has disabled offline download functionality and doesn't allow non-VSCode editors to use its source. These non-VSCode editors use mirrored sources to download extensions, so some extensions may not be available for download.&lt;/p&gt;

&lt;p&gt;You can use this &lt;a href="https://www.coze.cn/store/agent/7491642343327252489?bot_id=true" rel="noopener noreferrer"&gt;Coze&lt;/a&gt; agent by entering the Unique Identifier to download offline files.&lt;/p&gt;

&lt;p&gt;or you can also use the &lt;a href="https://github.com/Peter-007/VSIX_download_url" rel="noopener noreferrer"&gt;VSIX_download_url&lt;/a&gt; to download offline files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-48abff6d6d3b7af77970f35e6e32ce29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpictures.kazoottt.top%2F2025%2F10%2F20251020-48abff6d6d3b7af77970f35e6e32ce29.png" alt="Pasted image 20251020162148" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>cursor</category>
    </item>
    <item>
      <title>Share My Incorrect Usage Cases of Zustand</title>
      <dc:creator>KazooTTT</dc:creator>
      <pubDate>Wed, 18 Dec 2024 10:39:23 +0000</pubDate>
      <link>https://dev.to/kazoottt/share-my-incorrect-usage-case-of-zustand-55gn</link>
      <guid>https://dev.to/kazoottt/share-my-incorrect-usage-case-of-zustand-55gn</guid>
      <description>&lt;h2&gt;
  
  
  What is Zustand?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pmndrs/zustand" rel="noopener noreferrer"&gt;Zustand&lt;/a&gt; is a simple and easy-to-use state management library.&lt;/p&gt;

&lt;p&gt;While using &lt;a href="https://react-scan.com/" rel="noopener noreferrer"&gt;react-scan&lt;/a&gt;, I noticed that when I updated a state in the store in component A, it caused a re-render of component B, leading to significant performance issues.&lt;/p&gt;

&lt;p&gt;So, I revisited the documentation and realized that my previous usage of Zustand was incorrect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 1: Not using a single selector or shallow comparison to get state
&lt;/h2&gt;

&lt;p&gt;Here’s the previous implementation and the corresponding component. &lt;code&gt;useGlobalStore&lt;/code&gt; has more than just &lt;code&gt;uploadToServerProgress&lt;/code&gt; and &lt;code&gt;uploadStatus&lt;/code&gt; states.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uploadStatus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UploadStateContainer&lt;/span&gt;
      &lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;uploadStatus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;uploadStatus&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;uploadToServerProgress&lt;/code&gt; or &lt;code&gt;uploadStatus&lt;/code&gt; is updated, &lt;code&gt;UploadStateContainer&lt;/code&gt; re-renders (as expected). But when other states in &lt;code&gt;useGlobalStore&lt;/code&gt; are updated, &lt;code&gt;UploadStateContainer&lt;/code&gt; also re-renders (which is not expected).&lt;/p&gt;

&lt;p&gt;This is because &lt;code&gt;const { uploadToServerProgress, uploadStatus } = useGlobalStore();&lt;/code&gt; is shorthand for destructuring, which is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uploadStatus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;globalStore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In React, any update to &lt;code&gt;globalStore&lt;/code&gt; triggers a re-render of &lt;code&gt;UploadStateContainer&lt;/code&gt;. Therefore, we need to modify it as follows:&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution 1: Use a single selector
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploadStatus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution 2: Use &lt;code&gt;useShallow&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uploadStatus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;useShallow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploadToServerProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;uploadStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploadStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mistake 2: Not having sufficient granularity when using selectors
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;cameraData&lt;/code&gt; is obtained by subscribing to other services and contains data such as camera image and camera ID. The camera image is frequently updated data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CameraData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cameraBase64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// base64 encoded image&lt;/span&gt;
  &lt;span class="nl"&gt;cameraId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrentCamera&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cameraData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameraData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentCameraId&lt;/span&gt; &lt;span class="na"&gt;cameraId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cameraData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameraId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though this is using a single selector, when &lt;code&gt;cameraBase64&lt;/code&gt; updates, &lt;code&gt;cameraData&lt;/code&gt; will also update, causing &lt;code&gt;CurrentCameraId&lt;/code&gt; to re-render.&lt;/p&gt;

&lt;p&gt;To solve this, follow the principle of minimal granularity and only fetch the required data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CameraData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cameraBase64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// base64 encoded image&lt;/span&gt;
  &lt;span class="nl"&gt;cameraId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrentCamera&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cameraId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameraData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cameraId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentCameraId&lt;/span&gt; &lt;span class="na"&gt;cameraId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cameraId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mistake 3: Using multiple stores to manage different states, instead of using slices to group states
&lt;/h2&gt;

&lt;p&gt;In the official documentation &lt;a href="https://zustand.docs.pmnd.rs/guides/flux-inspired-practice" rel="noopener noreferrer"&gt;Flux-inspired practice - Zustand&lt;/a&gt;, it is mentioned that you should use a single store, not multiple stores for different states.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Recommended patterns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your application's global state should be located in a single Zustand store.&lt;/p&gt;

&lt;p&gt;If you have a large application, Zustand supports splitting the store into slices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Mistake 4: Accessing UI-unrelated state via selectors
&lt;/h2&gt;

&lt;p&gt;In a component, I had a &lt;code&gt;handleSave&lt;/code&gt; method that called an API to save data.&lt;/p&gt;

&lt;p&gt;Previously, I accessed the needed data through a selector within component A and then called the API to save it. But this was incorrect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;useShallow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;state2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSave&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In component B, I changed &lt;code&gt;state1&lt;/code&gt;, but since I accessed &lt;code&gt;state1&lt;/code&gt; in component A, the change would cause component A to re-render.&lt;/p&gt;

&lt;p&gt;The correct approach is to directly access the store inside the &lt;code&gt;handleSave&lt;/code&gt; method instead of passing the state via selectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComponentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useGlobalStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSave&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://zustand-demo.pmnd.rs/" rel="noopener noreferrer"&gt;Zustand&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/puxiao/notes/blob/master/zustand%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.md" rel="noopener noreferrer"&gt;master branch notes/zustand learning notes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://notes.boshkuo.com/docs/React/zustand#%E7%82%BA%E4%BD%95%E9%81%B8%E6%93%87%E4%BD%BF%E7%94%A8-zustand-" rel="noopener noreferrer"&gt;How to efficiently manage React local state? This time I chose Zustand! | Bosh's Technical Exploration Notes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>zustand</category>
      <category>react</category>
    </item>
  </channel>
</rss>
