<?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: Stefan Simic</title>
    <description>The latest articles on DEV Community by Stefan Simic (@simicdev).</description>
    <link>https://dev.to/simicdev</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%2F1604317%2Fec7bd411-e3ca-4690-a8f7-f49c0bc38fc7.png</url>
      <title>DEV Community: Stefan Simic</title>
      <link>https://dev.to/simicdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/simicdev"/>
    <language>en</language>
    <item>
      <title>next js</title>
      <dc:creator>Stefan Simic</dc:creator>
      <pubDate>Thu, 30 Jan 2025 17:50:10 +0000</pubDate>
      <link>https://dev.to/simicdev/next-js-h9c</link>
      <guid>https://dev.to/simicdev/next-js-h9c</guid>
      <description></description>
      <category>nextjs</category>
    </item>
    <item>
      <title>Callback Refs vs. useEffect: When to use which</title>
      <dc:creator>Stefan Simic</dc:creator>
      <pubDate>Wed, 29 Jan 2025 08:47:49 +0000</pubDate>
      <link>https://dev.to/simicdev/callback-refs-vs-useeffect-when-to-use-which-1icd</link>
      <guid>https://dev.to/simicdev/callback-refs-vs-useeffect-when-to-use-which-1icd</guid>
      <description>&lt;p&gt;In React, managing side effects and interacting with the DOM are crucial aspects of component development. Two powerful tools for this are useEffect and callback refs. While useEffect is a versatile hook for handling various side effects, callback refs offer a more direct and potentially more performant approach in specific scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Callback Refs
&lt;/h3&gt;

&lt;p&gt;Callback refs provide a way to access the actual DOM element directly within a functional component. You pass a callback function to the ref attribute of an element. This callback function receives the DOM element as an argument, allowing you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Directly manipulate the DOM: Set focus, resize elements, apply styles, and more.&lt;/li&gt;
&lt;li&gt;Interact with third-party libraries: Integrate with libraries that work directly on DOM elements (e.g., map libraries, canvas libraries).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Use Callback Refs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Direct DOM Manipulation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you need to set up or clean up DOM-related logic (e.g., focus management, resizing elements).
-Callback refs provide direct access to the DOM element, allowing for precise and efficient manipulations.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Third-party Libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When initializing or interacting with libraries that work directly on DOM elements (e.g., integrating with a map library, handling canvas interactions).
-Callback refs enable you to pass the DOM element directly to the library's API.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Avoiding Re-render Dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When useEffect dependencies can cause unnecessary re-renders, potentially impacting performance.&lt;/li&gt;
&lt;li&gt;By using callback refs, you can avoid including the DOM element itself in the useEffect dependency array, reducing the number of re-renders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: Focus Management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;InputWithFocus&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;inputRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;handleRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&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="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scroll to Bottom Example
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Callback Ref:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt; &lt;span class="p"&gt;}&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Chat&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;messagesEndRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;scrollToBottom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&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;handleSendMessage&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;setMessages&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New Message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; 
    &lt;span class="nf"&gt;scrollToBottom&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;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;300px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;overflowY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&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="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;both&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; 
           &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSendMessage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;h4&gt;
  
  
  useEffect:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Chat&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;messagesEndRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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;scrollToBottom&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="nx"&gt;messages&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;scrollToBottom&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;'&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;handleSendMessage&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;setMessages&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New Message&lt;/span&gt;&lt;span class="dl"&gt;"&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;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;300px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;overflowY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&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="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;both&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; 
           &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messagesEndRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSendMessage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;h3&gt;
  
  
  Choosing the Right Approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For direct DOM manipulations and when avoiding unnecessary re-renders is crucial, callback refs are generally preferred.&lt;/li&gt;
&lt;li&gt;For simpler scenarios or when performance is not a primary concern, useEffect can be a suitable choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding the strengths of both callback refs and useEffect, you can make informed decisions about how to manage side effects and interact with the DOM in your React components effectively.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>🔥 Free Database &amp; API in 10 Minutes</title>
      <dc:creator>Stefan Simic</dc:creator>
      <pubDate>Tue, 28 Jan 2025 11:38:19 +0000</pubDate>
      <link>https://dev.to/simicdev/-ol</link>
      <guid>https://dev.to/simicdev/-ol</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/daniel_jones" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2579633%2Ffe3f3b59-7b3f-485b-8d30-1905cfc9fa51.jpg" alt="daniel_jones"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/daniel_jones/quick-guide-build-a-backend-api-service-in-minutes-with-cloudflare-pages-d1-database-nextjs-4njj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Start Your Free Database and API Service in Just 10 Minutes！🔥🔥🔥(With GitHub repository)&lt;/h2&gt;
      &lt;h3&gt;Daniel Jones ・ Dec 23 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Supabase Workflows: From Dashboard to Git-Based Development</title>
      <dc:creator>Stefan Simic</dc:creator>
      <pubDate>Tue, 28 Jan 2025 10:42:30 +0000</pubDate>
      <link>https://dev.to/simicdev/supabase-workflows-from-dashboard-to-git-based-development-4080</link>
      <guid>https://dev.to/simicdev/supabase-workflows-from-dashboard-to-git-based-development-4080</guid>
      <description>&lt;p&gt;Supabase has been gaining a lot of love lately—and for good reason. It’s a powerful backend-as-a-service that combines Postgres, authentication, storage, and real-time capabilities, all wrapped in a developer-friendly package. If you’ve worked with Firebase before, Supabase can feel like a step up, especially if you’re excited about SQL and database-first development.&lt;/p&gt;

&lt;p&gt;But as projects grow, so do the challenges. If you’ve ever found yourself hesitant to make changes because reverting feels risky, or struggling to keep track of row-level security (RLS) policies and database functions, you’re not alone. The good news? Supabase offers tools and workflows to handle these challenges—and they’re more powerful than you might think.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore how to transition from using the Supabase dashboard for quick edits to adopting a Git-based, scalable workflow for serious development.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Dashboard Dilemma
&lt;/h2&gt;

&lt;p&gt;When starting out with Supabase, the dashboard feels intuitive and approachable. You can quickly create tables, define RLS policies, and even write functions. But as your project grows, this approach can get messy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Version Control&lt;/strong&gt;: Changes made on the dashboard are hard to track, let alone revert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risky Changes&lt;/strong&gt;: Touching production data or policies directly can lead to errors that are hard to debug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration Issues&lt;/strong&gt;: For teams, the lack of a proper workflow makes collaboration cumbersome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dashboard is perfect for prototyping, but for larger projects, you need something more robust.&lt;/p&gt;




&lt;h2&gt;
  
  
  Supabase’s Local Development Workflow
&lt;/h2&gt;

&lt;p&gt;Here’s where Supabase CLI and local development come into play. Supabase offers a workflow that allows you to manage your database schema, policies, and migrations locally—all version-controlled in Git. This bridges the gap between rapid prototyping and professional development practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Can Do with the Supabase CLI:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Spin Up a Local Environment&lt;/strong&gt;: Run a local version of Supabase (Postgres, Auth, etc.) on your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate Migrations&lt;/strong&gt;: Every change to your database schema can be captured as a migration file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Safely&lt;/strong&gt;: Experiment locally without touching production data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control Everything&lt;/strong&gt;: Migrations, SQL functions, and even RLS policies can all live in Git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply Migrations to Production&lt;/strong&gt;: Confidently push changes to your live environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Getting Started:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the CLI&lt;/strong&gt;: &lt;a href="https://supabase.com/docs/guides/cli" rel="noopener noreferrer"&gt;Follow Supabase’s guide&lt;/a&gt; to set up the CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Up a Local Project&lt;/strong&gt;: Use &lt;code&gt;supabase start&lt;/code&gt; to spin up a local environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make Changes Locally&lt;/strong&gt;: Modify your schema, add RLS policies, or create functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate Migrations&lt;/strong&gt;: Use &lt;code&gt;supabase db diff&lt;/code&gt; to generate migration files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit to Git&lt;/strong&gt;: Track your changes just like you would with application code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy Changes&lt;/strong&gt;: Use &lt;code&gt;supabase db push&lt;/code&gt; to apply migrations to production.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Best Practices for Supabase Workflows
&lt;/h2&gt;

&lt;p&gt;To get the most out of Supabase, adopt these best practices:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Organize Your SQL&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Keep your database functions, triggers, and RLS policies modular and reusable. Store them in version-controlled &lt;code&gt;.sql&lt;/code&gt; files and structure them logically—for example, separate folders for migrations, functions, and policies.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Leverage Git for Everything&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Treat your database schema like application code. Version-control all changes to your schema, policies, and functions. This ensures your team can collaborate effectively and roll back changes when needed.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Test Locally Before Deploying&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Never experiment on your production database. Use the local environment to test schema changes, functions, and policies. This minimizes the risk of breaking your app in production.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;Track Your Workflow with Tools&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;While Supabase CLI is powerful, consider using additional tools to stay organized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Notion or Trello&lt;/strong&gt;: Document your policies, functions, and workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postico or DBeaver&lt;/strong&gt;: Manage your database visually if needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipelines&lt;/strong&gt;: Automate the deployment of migrations to production.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. &lt;strong&gt;Keep RLS Policies Simple&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Row-Level Security is one of Supabase’s strongest features, but overly complex policies can be hard to debug. Start simple, test thoroughly, and build incrementally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Pitfalls (and How to Avoid Them)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skipping Local Testing&lt;/strong&gt;: Always test your migrations and policies locally before deploying. It’s easy to overlook this step, but it can save you from production headaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Overcomplicating Policies&lt;/strong&gt;: Avoid writing overly complex RLS policies upfront. Build policies iteratively, and document them well for clarity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Relying Solely on the Dashboard&lt;/strong&gt;: The dashboard is great for quick prototyping, but for larger projects, switch to a Git-based workflow sooner rather than later.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Supabase is more than just a Firebase alternative—it’s a robust backend platform that scales beautifully with the right workflow. By adopting Supabase CLI, local development, and a Git-based workflow, you can confidently build and grow your projects without fear of breaking production.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Ultimate Scaffolder for Next.js and Supabase development</title>
      <dc:creator>Stefan Simic</dc:creator>
      <pubDate>Tue, 28 Jan 2025 09:59:56 +0000</pubDate>
      <link>https://dev.to/simicdev/ultimate-scaffolder-for-nextjs-and-supabase-development-3k0l</link>
      <guid>https://dev.to/simicdev/ultimate-scaffolder-for-nextjs-and-supabase-development-3k0l</guid>
      <description>&lt;p&gt;Hey there, awesome devs! 👋 Are you tired of spending hours setting up your Next.js projects with Supabase and shadcn/ui? Well, I’ve got some exciting news for you! 🎉&lt;/p&gt;

&lt;p&gt;Introducing the &lt;strong&gt;Next.js Supabase shadcn/ui&lt;/strong&gt; Scaffolder&lt;br&gt;
I’m thrilled to share a tool that’s going to make your life so much easier. Say hello to the Next.js Supabase shadcn/ui Scaffolder! This nifty package is designed to kickstart your Next.js projects with Supabase integration and shadcn/ui components in just a few minutes. No more tedious setup processes or configuration headaches!&lt;/p&gt;

&lt;p&gt;What’s in the Box? 📦&lt;br&gt;
Our scaffolder is packed with features to get you up and running in no time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js Setup&lt;/strong&gt;: Get a fresh Next.js project ready to go.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase Integration&lt;/strong&gt;: Seamlessly connect your app to Supabase for all your backend needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shadcn/ui Components&lt;/strong&gt;: Beautiful, accessible components at your fingertips.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript Support&lt;/strong&gt;: Because who doesn’t love some type safety?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible Routing&lt;/strong&gt;: Choose between the classic Pages Router or the new App Router.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TailwindCSS Integration&lt;/strong&gt;: Optionally include TailwindCSS for easy styling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Setup&lt;/strong&gt;: Automatic configuration of your Supabase environment variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started is a Breeze🌬️
&lt;/h2&gt;

&lt;p&gt;Ready to dive in? Here’s how you can get started:&lt;/p&gt;

&lt;p&gt;Install the package globally:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g next-supabase-starter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initialize project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;next-supabase init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/next-supabase-starter" rel="noopener noreferrer"&gt;next-supabase-starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/stefkosimic/next-supabase-starter" rel="noopener noreferrer"&gt;Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>supabase</category>
      <category>javascript</category>
      <category>shadcn</category>
    </item>
  </channel>
</rss>
