Stale State in Asynchronous Updates in ReactJS

November 16, 2024 Leave a comment

The Problem: React’s state updates are asynchronous and sometimes lead to a problem known as “stale state.” This happens when you attempt to read or update the state within an asynchronous function (like setTimeout, setInterval, or an API call), but the state you access is outdated because React does not guarantee immediate state updates.

For example:

import React, { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

const incrementAfterDelay = () => {
setTimeout(() => {
setCount(count + 1); // `count` may still be 0 here, causing a stale state issue
}, 1000);
};

return (
<div>
<p>Count: {count}</p>
<button onClick={incrementAfterDelay}>Increment After Delay</button>
</div>
);
}

export default Counter;

Here, the count used inside the setTimeout callback may not reflect the latest state when the delay completes.


The Solution: Using a Functional State Update

React provides a way to avoid stale state issues by using functional updates in setState. Instead of relying on the current state value, you can pass a function to setState that receives the most up-to-date state as an argument.

Here’s the fixed version:

import React, { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

const incrementAfterDelay = () => {
setTimeout(() => {
setCount((prevCount) => prevCount + 1); // Use the functional update form
}, 1000);
};

return (
<div>
<p>Count: {count}</p>
<button onClick={incrementAfterDelay}>Increment After Delay</button>
</div>
);
}

export default Counter;

Now, prevCount always holds the most recent value of count, avoiding the stale state issue.


Why This is Interesting:

  1. Many developers, especially those new to React, stumble upon this problem unknowingly and might spend hours debugging.
  2. This introduces a subtle yet powerful feature of React’s state management—functional updates.
  3. The concept is applicable across various asynchronous scenarios in React

#ReactJS

Setup a Javascript server for running angular app using st package

May 31, 2018 Leave a comment

If you need a Javascript web server to run angular apps. Please follow the below steps.

1. Install node.

2. Go to the working directory and install st package (https://www.npmjs.com/package/st)

12

3. Create a server.js file in the working directory with the following code

var st = require('st')
var http = require('http')
http.createServer(st({path:process.cwd(),cache:false})).listen(1337)
console.log('Running server at localhost:1337/')

 

4. Run the server.js using node

13

5. Create an index.html file in the working directory and check the server path

15

14

Happy coding 🙂

HTTP Error 404.3 – Not Found The page you are requesting cannot be served because of the extension configuration.

April 21, 2015 Leave a comment

Resolve this MIME issue by adding the extension in web.config


<configuration>
 <system.web>
 <compilation debug="true" targetFramework="4.0" />
 </system.web>
 
 <system.webServer>
 <staticContent>
 <remove fileExtension=".json" />
 <mimeMap fileExtension=".json" mimeType="application/json" />
 </staticContent>
 </system.webServer>

</configuration>

Categories: ASP.NET Tags: , ,

Convert sql query result in to JSON

October 30, 2014 Leave a comment

DECLARE 
 @TableName NVARCHAR(512),
 @sql NVARCHAR(MAX),
 @xml XML;


SET @TableName = N'Customers';

SET @sql = N'SELECT @xml = CONVERT(NVARCHAR(MAX), (
 SELECT top 20 * FROM ' + @TableName + ' FOR XML path, root));';

EXEC sp_executesql @sql, N'@xml XML OUTPUT', @xml OUTPUT;

SELECT dbo.ToJSON (@xml)


USE [DB]
GO
/****** Object: UserDefinedFunction [dbo].[ToJSON] Script Date: 10/30/2014 19:24:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ToJSON] (@XMLResult XML)
RETURNS NVARCHAR(MAX)
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @JSONVersion NVARCHAR(MAX), @Rowcount INT
SELECT @JSONVersion = '', @rowcount=COUNT(*) FROM @XMLResult.nodes('/root/*') x(a)
SELECT @JSONVersion=@JSONVersion+
STUFF(
 (SELECT TheLine FROM 
 (SELECT ',
 {'+
 STUFF((SELECT ',"'+COALESCE(b.c.value('local-name(.)', 'NVARCHAR(255)'),'')+'":"'+
 REPLACE( --escape tab properly within a value
 REPLACE( --escape return properly
 REPLACE( --linefeed must be escaped
 REPLACE( --backslash too
 REPLACE(COALESCE(b.c.value('text()[1]','NVARCHAR(MAX)'),''),--forwardslash
 '\', '\\'), 
 '/', '\/'), 
 CHAR(10),'\n'), 
 CHAR(13),'\r'), 
 CHAR(09),'\t') 
 +'"' 
 FROM x.a.nodes('*') b(c) 
 FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'')+'}'
 FROM @XMLResult.nodes('/root/*') x(a)
 ) JSON(theLine)
 FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)' )
,1,1,'')
IF @Rowcount>1 RETURN '['+@JSONVersion+'
]'
RETURN @JSONVersion
END

Categories: MS SQL Tags: , , ,

Call WCF service from Excel

October 13, 2014 Leave a comment

We can call a WCF service from the excel work sheet as client.

First construct a WCF service by creating a WCF Service Library from Visual Studio 2012(am using this version of VS).

Am using the same test template provided by the Visual Studio

1

Remove all composite type stuffs from the source files Service1.cs and IService1.cs (we don’t need for now)

So the new files will look like this

A small change I made was the input parameter changed to string.

3      4

Next main thing is App.config.

You can use http or tcp as service protocol. I described both in App.config (tcp configuration is commented)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

 <system.web>
 <compilation debug="true" />
 </system.web>
 <!-- When deploying the service library project, the content of the config file must be added to the host's 
 app.config file. System.Configuration does not support config files for libraries. -->
 <system.serviceModel>
 <services>
 <service behaviorConfiguration="MyTestWcfService.Service1Behavior" name="MyTestWcfService.Service1">

 <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
 contract="MyTestWcfService.IService1">
 <identity>
 <dns value="localhost" />
 </identity>
 </endpoint>

 <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
 contract="IMetadataExchange" />


 <!--<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
 contract="MyTestWcfService.IService1">
 <identity>
 <dns value="localhost" />
 </identity>
 </endpoint>
 
 <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
 contract="IMetadataExchange" />-->
 
 
 <host>
 <baseAddresses>
 <!--<add baseAddress="net.tcp://localhost:8733/Test/MyTestWcfService/Service1/" />-->
 <add baseAddress="http://localhost:8733/Test/MyTestWcfService/Service1/" />
 </baseAddresses>
 </host>
 </service>
 </services>
 <behaviors>
 <serviceBehaviors>
 <behavior name="MyTestWcfService.Service1Behavior">
 <serviceMetadata httpGetEnabled="false" />
 <serviceDebug includeExceptionDetailInFaults="false" />
 </behavior>
 </serviceBehaviors>
 </behaviors>
 </system.serviceModel>

</configuration>

Run the service

5

You have done with the service end.

Lets start the Excel and press Alt + F11. You can see something like this

6

Double click sheet1 from the left side.

From the new window. Select Worksheet from the first drop down and Select change from the second drop down.

7

Remove Worksheet_SelectionChange function definition as we don’t need in this demo.


Private Sub Worksheet_Change(ByVal x As Range)
Dim addr As String
addr = "service:mexAddress=""http://localhost:8733/Test/MyTestWcfService/Service1/mex"","
addr = addr + "address=""http://localhost:8733/Test/MyTestWcfService/Service1/"","
addr = addr + "contract=""IService1"", contractNamespace=""http://tempuri.org/"","
addr = addr + "binding=""BasicHttpBinding_IService1"", bindingNamespace=""http://tempuri.org/"""

Dim service1 As Object
Set service1 = GetObject(addr)
Dim text As String
text = Cells.Item(x.Row, x.Column)
MsgBox service1.GetData(text)

End Sub

We can get the service object as service1 by calling GetObject(addr).

The above address configuration is for http protocol. For tcp please use this address configuration (Uncomment the tcp stuffs from the service too if you are using tcp)

addr = "service:mexAddress=""net.tcp://localhost:8733/Test/MyTestWcfService/Service1/mex"","
addr = addr + "address=""net.tcp://localhost:8733/Test/MyTestWcfService/Service1/"","
addr = addr + "contract=""IService1"", contractNamespace=""http://tempuri.org/"","
addr = addr + "binding=""NetTcpBinding_IService1"", bindingNamespace=""http://tempuri.org/"""

You are done. The service accept the value typed in a cell and show it in Message Box.

Save the document as macro enabled document (Book1.xlsm)

You can see the the output as

8

Thanks for reading.

Happy coding 🙂

how to get query string parameters in javascript

August 18, 2014 Leave a comment
function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

Suppose url is
http://localhost:55218/Source/index.html?qProjectId=881&qType=build
We can get the value by calling

var projId = getParameterByName('qProjectId'); //881

Happy coding 🙂

HTML5 textbox tap issue in IPhone

July 7, 2014 1 comment

Sometimes the textbox not get focus on tap and the app gets stuck for some time.

In order to resolve this issue, include this code in document.ready

document.addEventListener("touchend", function (e) {
if (e.target.nodeName.toString().toUpperCase() == 'INPUT' || e.target.nodeName.toString().toUpperCase() == 'TEXTAREA') {
e.preventDefault();
e.target.focus();
});

Happy coding 🙂

Categories: HTML5

Preserving Check Box States PagedList MVC3

January 9, 2014 Leave a comment

🙂 It can be done using a session variable.

Using the following javascript snippet we can get the coma seperated selected and deselected check box ids on paging

var searchSelectedIDs = $("#table1 input:checkbox:checked").map(function ()
{
return $(this).val();
}).get()
var searchDeSelectedIDs = $("#table1 input:checkbox:not(:checked)").map(function ()
{
return $(this).val();
}).get()
$.ajax({
url: '/Utility/SaveContactIDs?SelectedIDs=' + searchSelectedIDs +'&DeSelectedIDs='+searchDeSelectedIDs,
type: 'GET',
cache: false,
success: function (result) {
},
error: function (p, s, r) {    }
});

In the controller

public string SaveContactIDs(string SelectedIDs, string DeSelectedIDs)
{

string contactSearch = Convert.ToString(Session["ContactSearchIDs"]);

if (contactSearch != "")
{
string[] sIds = SelectedIDs.Split(',');

foreach (string str in sIds)
{
if (!contactSearch.Split(',').Contains(str))
{
Session["ContactSearchIDs"] = Session["ContactSearchIDs"] + str + ",";
}

}


}
else
{
Session["ContactSearchIDs"] = SelectedIDs + ",";
}

string[] deselectedValues = DeSelectedIDs.Split(',');
string ids = Convert.ToString(Session["ContactSearchIDs"]);
foreach (string str in deselectedValues)
{
if (str.Trim() != "")
{
if (ids.Split(',').Contains(str))
{
ids = ids.Remove(ids.IndexOf(str), str.Length + 1);
}
}

}



Session["ContactSearchIDs"] = ids;

return "success";
}



in cshtml to show check box state true or false based on session value

@if(Session["ContactSearchIDs"] != null)
{

if (Convert.ToString(Session["ContactSearchIDs"]).Split(',').Contains(item.CONTACT_ID.ToString()))
{

@Html.CheckBox(item.CONTACT_ID.ToString(), true, new { @id = item.CONTACT_ID, @name = "chkSelect[]", @value = item.CONTACT_ID.ToString() })
}
else
{
@Html.CheckBox(item.CONTACT_ID.ToString(), false, new { @id = item.CONTACT_ID, @name = "chkSelect[]", @value = item.CONTACT_ID.ToString() })

}

}
else
{
@Html.CheckBox(item.CONTACT_ID.ToString(), false, new { @id = item.CONTACT_ID, @name = "chkSelect[]", @value = item.CONTACT_ID.ToString() })

}

Happy coding 🙂

 

Execute a method every time interval automatically c#

November 8, 2013 Leave a comment

To call a method automatically for every time interval, we can use timers in C#

See the code below.

class Program
{
public static System.Timers.Timer aTimer;
static void Main(string[] args)
{
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(RunThis);
aTimer.AutoReset = true;
aTimer.Enabled = true;
Console.ReadLine();
}
private static void RunThis(object source, ElapsedEventArgs e)
{
Console.WriteLine("Print this in every 10 seconds");
}
}

Happy coding 🙂

Setting up Visual SVN source control with Visual Studio and Tortoise Client

October 3, 2013 Leave a comment

My team faced many issues without a proper source control management.

Some issues are Team project, backup updated sources with different dates in folder, lacking update comments, etc

I got a cool svn server for managing different versions of source files. Visual SVN and its plugins for Visual Studio.

You can see here

http://www.visualsvn.com/

Download and Install Visual SVN Server to setup svn server.

Download and Install Visual SVN as the plugin for your all versions of Visual Studio.

One more thing remaining. Download Tortoise svn client

http://www.visualsvn.com/visualsvn/download/tortoisesvn/

Please install appropriate version, if your system is 64 bit, install 64 bit version.

Notes :

  • Install the svn server in a dedicated system with a particular port number (use https)
  • Make a repository to store your sources in the svn server, also make users (developers) to access the server.
  • Add solution to the svn server repository from developer’s visual studio.

Image

  • Connect to server svn, its like

https://srishti-pc:4499/svn/sandbox/TestProject/trunk

sandbox is the name of your repository. You can create many repositories in server.

Image

  • After finish you can commit your solution, so it would be your first version of source code.
  • Many developers can work on that and make different versions of source with update comments.
  • Main things are Update and Commit

Update : Get updated source from the repository

Commit : Update (with comments)  repository with your new version of source code

Happy coding with svn 🙂