<?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: Darnell</title>
    <description>The latest articles on DEV Community by Darnell (@drant_dumani).</description>
    <link>https://dev.to/drant_dumani</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%2F616860%2Fff0e5e93-3810-41dd-ac0c-c5e37b8b6032.png</url>
      <title>DEV Community: Darnell</title>
      <link>https://dev.to/drant_dumani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/drant_dumani"/>
    <language>en</language>
    <item>
      <title>Designing a database for a social media app</title>
      <dc:creator>Darnell</dc:creator>
      <pubDate>Sun, 30 Mar 2025 07:10:46 +0000</pubDate>
      <link>https://dev.to/drant_dumani/designing-a-database-for-a-social-media-app-1908</link>
      <guid>https://dev.to/drant_dumani/designing-a-database-for-a-social-media-app-1908</guid>
      <description>&lt;p&gt;Making clones of websites and recreating their functionality is a good way to develop skills and even challenge oneself in ways you may not have expected to. So as a challenge to myself, I decided to create a clone of the social media website, &lt;a href="https://www.tumblr.com/" rel="noopener noreferrer"&gt;Tumblr&lt;/a&gt;. I chose Tumblr because it's the social media website that I've used the most.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Planning Phase
&lt;/h2&gt;

&lt;p&gt;The biggest mistake to make with any large project is to open VSCode and stare at your code editor for a while, wondering where to begin (and often times even rewriting code you just wrote after realizing what else needs to be done). The best way to start a project like this is to ask questions about what needs to be done, how the web app is supposed to behave for users. Having a full plan reduces roadblocks and gives you a clear map of what your end result is supposed to be.&lt;/p&gt;

&lt;p&gt;Some questions I had to ask myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to handle user authentication?&lt;/li&gt;
&lt;li&gt;What will my routes look like, and what data will they require / send to the user?&lt;/li&gt;
&lt;li&gt;What are the most important features for my clone website (an important question, as I'm only one person. Tumblr as a whole is managed by hundreds of employees)&lt;/li&gt;
&lt;li&gt;What persistent data will I need to handle?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the sake of this article, I'll only focus on the answer I came up with for the last one for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What persistent data will I need to handle?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Users
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Users need a username. &lt;/li&gt;
&lt;li&gt;For their credentials, I'll need to store their email address and their (hashed) password. &lt;/li&gt;
&lt;li&gt;Users should be able to customize their profiles. Unlike the above two, this is optional. Users can save some info about themselves in an "About" section. They can also save a header image for their blog, and a profile image. For this project, I won't store the images in my database. I'll use cloudinary for that, and I'll store the links to the images (and the image ids) in my database instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Posts
&lt;/h3&gt;

&lt;p&gt;Here's where things got complicated. Tumblr has a reblog feature, which allows users to share posts from other blogs to their own. They can't edit content written by other users, but they can add their own content to posts. Reblogged posts are brand new posts that "belong" to the one reblogging. So I'll need to replicate that functionality. &lt;/p&gt;

&lt;p&gt;Another thing to consider is how shared posts function when the original poster edits them. Imagine if someone made a post saying "I love cats". A thousand other users can share / reblog these posts, only to have this post suddenly change on them when the original poster edits the post to say, "I hate cats" instead. Tumblr doesn't allow this behavior, and editing a post will only edit that post for the specific user. &lt;/p&gt;

&lt;p&gt;There's also the matter of post content. Posts on tumblr can be made up of text, music, videos, photos, or links. Then you need a way to manage which part of a post was created by which user, as well as what type of content the post contains.&lt;/p&gt;

&lt;p&gt;My solution to this involved breaking posts down into segments. A post could be made up of several segments, which would be responsible for the post content. And the content would be displayed in order of when the segment was created, starting with the oldest segment.&lt;/p&gt;

&lt;p&gt;This allows me to simplify the posts themselves. Now I just need to care about the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When was a post created? (a timestamp)&lt;/li&gt;
&lt;li&gt;Who made the post? (Its author)&lt;/li&gt;
&lt;li&gt;If the post is a reblog, what is the original post?&lt;/li&gt;
&lt;li&gt;If the post is reblog, what post was it immediately reblogged from?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Segments
&lt;/h3&gt;

&lt;p&gt;As said above, segments will be responsible for the actual post content. Whenever a user creates a new post or adds content to a reblogged post, they create a post segment. Whenever a user edits a post, they will only be able to a segment that they themselves have created. As far as Segment data goes, I'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The segment author&lt;/li&gt;
&lt;li&gt;When the segment was created&lt;/li&gt;
&lt;li&gt;What type of content a segment holds (text, audio, video, etc). This is so the front end knows how to render the content. Tumblr allows users to mix and match post types, so I could technically use JSON to store post segment types. But I decided to keep it simple&lt;/li&gt;
&lt;li&gt;The content of the post segment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Replies
&lt;/h3&gt;

&lt;p&gt;Users can leave comments, or replies, on posts. Fortunately, tumblr keeps this pretty simple. Replies can only be text. So there isn't much to track here aside from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who made the reply&lt;/li&gt;
&lt;li&gt;The content of the reply&lt;/li&gt;
&lt;li&gt;The post the reply is being made on&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tags
&lt;/h3&gt;

&lt;p&gt;Tumblr has a post tagging system, which lets users search for posts that aren't reblogs by tag, and lets them search their own blogs for any posts that they've tagged. Tags should be unique (multiple tags named "travel" don't need to exist). The only thing to worry about as far as tags are concerned is the content of the tag.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relations
&lt;/h3&gt;

&lt;p&gt;Now it's important to figure out how all of this data is supposed to relate to each other.&lt;/p&gt;

&lt;p&gt;Users -&amp;gt; Posts: One to many relationship. Users can create multiple posts. Each post is only created by one user.&lt;/p&gt;

&lt;p&gt;Users -&amp;gt; Segments: This is the same relationship as users to posts.&lt;/p&gt;

&lt;p&gt;Posts &amp;lt;-&amp;gt; Segments: Many to many relationship. A post can be made up of multiple segments. Segments can be associated with multiple posts via reblogging.&lt;/p&gt;

&lt;p&gt;Posts &amp;lt;-&amp;gt; Tags: Many to many relationship. A post can have several tags. And the same tag can be associated with multiple posts.&lt;/p&gt;

&lt;p&gt;Users following Users: Every social media site needs to have a follow feature! Users can follow many users, and users can be followed by many other users.&lt;/p&gt;

&lt;p&gt;Users liking Posts: Users can like many posts. Posts can be liked by many users. This is another many to many relationship. For reblogged posts, likes are shared between them and the parent post. &lt;/p&gt;

&lt;p&gt;Post -&amp;gt; Replies: Posts can have many replies, but replies are unique to one post. This is a one to many relationship. &lt;/p&gt;

&lt;p&gt;After all of this, we can now decide what our database schema is going to look like.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftulvr7880ld7w39t03ga.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftulvr7880ld7w39t03ga.png" alt="Image description" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just one of many steps. In my next post, I'll delve into using an ORM, writing tests, and creating my routes and controllers.&lt;/p&gt;

</description>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A quick guide on closures</title>
      <dc:creator>Darnell</dc:creator>
      <pubDate>Tue, 12 Sep 2023 21:46:45 +0000</pubDate>
      <link>https://dev.to/drant_dumani/a-quick-guide-on-closures-4ebj</link>
      <guid>https://dev.to/drant_dumani/a-quick-guide-on-closures-4ebj</guid>
      <description>&lt;p&gt;Closures are a powerful tool in JavaScript. If you've been writing event listeners, your own custom hooks, or even using the default hooks React is built with, then you've been using closures already. But what specifically are closures? I'll attempt to explain what they are in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;p&gt;In order to understand closures, we need to understand scope. To summarize, when something is locally scoped, it can only be "seen" by other things within its scope. If I declare a local variable inside of a code block, then it can't be seen by anything outside of that block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;localBlock&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//this prints 4&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//x is undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In human terms, this is kind of like entering a soundproof room with your friend and telling them a secret. No one outside of the room will hear or know it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closures
&lt;/h2&gt;

&lt;p&gt;With scopes out of the way, we can focus on the reason I'm making this post. Closures are a way for JavaScript to "remember" or "preserve" variables that are no longer in scope. Let's consider the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;outerScope&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;innerScope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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="nx"&gt;innerScope&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//prints undefined&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;closureExample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;outerScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;closureExample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//prints 100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function &lt;code&gt;outerScope&lt;/code&gt; defines two variables. It assigns &lt;code&gt;x&lt;/code&gt; the value of 100, and &lt;code&gt;innerScope&lt;/code&gt; the value of a function. It then returns the function, which still has access to &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;innerScope&lt;/code&gt; technically has access to everything that was defined inside of &lt;code&gt;outerScope&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In human terms, I'll reuse the secret room analogy from before. You  and your friend enter a soundproof room and you tell them a secret. Nobody outside of the room knows what the secret is. But your friend will still know the secret even after they've left the room and they're free to tell whoever they want.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are closures used for?
&lt;/h2&gt;

&lt;p&gt;In the beginning of this post, I named some ways in which you may have been using closures already. Closures are also used for currying / nesting functions, factory functions, and partial applications.&lt;/p&gt;

&lt;p&gt;As a (somewhat contrived) example, let's say you're writing a small game in React. You have a button a user can click to increment a counter. After 5 seconds have passed, an alert box pops up to show the user how many times they clicked the button. The code would look something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&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;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;increment&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="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&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;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`You clicked the button &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; times!`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;5000&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="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="o"&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;increment&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;Counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;counter&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;/button&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="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&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;App&lt;/span&gt;&lt;span class="o"&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 this example, the anonymous function we passed to setTimeout contains a closure around the initial value for counter. No matter how many times we click the button, the alert box will tell us &lt;code&gt;You clicked the button 0 times!&lt;/code&gt; So when our app component mounts, the useEffect function runs, and our anonymous function that we passed to setTimeout "remembers" the value for counter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra: Why this happens and fixing our component
&lt;/h2&gt;

&lt;p&gt;If you're wondering why &lt;code&gt;useEffect&lt;/code&gt; doesn't work the way you want it to, it's because of how React hooks handle state. State is never mutated. React really doesn't want us to do this. When we update state with our &lt;code&gt;setCounter&lt;/code&gt; function, we're creating an entirely new value altogether. This new value isn't tracked by the function in our useEffect at all.&lt;/p&gt;

&lt;p&gt;To fix this, we would some way to track our value without mutating our state. Fortunately, the useRef hook allows us to do just that. To keep things brief, the useRef hook creates an object with a &lt;code&gt;current&lt;/code&gt; property. We'll assign the current property to our counter variable. The object created by useRef CAN be mutated, so we never have to worry about losing the value we assign to it. Every time we click the button, our component re-renders and our countRef object's current property is assigned the new counter value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&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;countRef&lt;/span&gt; &lt;span class="o"&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;useRef&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;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;increment&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="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

  &lt;span class="nx"&gt;countRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counter&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;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="nx"&gt;setTimeout&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;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`You clicked the button &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;countRef&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="s2"&gt; times!`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;5000&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="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="o"&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;increment&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;Counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;counter&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;/button&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="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&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;App&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
