<?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: Tanmay Banerjee</title>
    <description>The latest articles on DEV Community by Tanmay Banerjee (@tanmaybanerjee).</description>
    <link>https://dev.to/tanmaybanerjee</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%2F645232%2F5ed47042-fba3-4c79-86c0-7893d6760142.jpeg</url>
      <title>DEV Community: Tanmay Banerjee</title>
      <link>https://dev.to/tanmaybanerjee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tanmaybanerjee"/>
    <language>en</language>
    <item>
      <title>KendoReactChallenge : Feedback Analyzer</title>
      <dc:creator>Tanmay Banerjee</dc:creator>
      <pubDate>Fri, 26 Sep 2025 15:36:42 +0000</pubDate>
      <link>https://dev.to/tanmaybanerjee/kendoreactchallenge-feedback-analyzer-8bm</link>
      <guid>https://dev.to/tanmaybanerjee/kendoreactchallenge-feedback-analyzer-8bm</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kendoreact-2025-09-10"&gt;KendoReact Free Components Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;FeedbackAnalyzer is a streamlined SaaS web app that helps small and medium-sized businesses (SMBs) collect, analyze, and act on customer feedback from multiple channels like emails, surveys, and social media. It differentiates itself with "AI-assisted" sentiment mapping (using simple NLP rules or mock integrations like OpenAI APIs) to categorize feedback into themes (e.g. "Product Quality", "Service", "Prising"), predict churn risks, and suggest action items. Users upload or input feedback, view dashboards with trends, and export reports. The uniqueness comes from its "flow builder"—a visual tool to automate feedback loops, like triggering follow-up emails based on negative sentiment which could be future scope along with exporting a report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Below is the codesandbox link of above describe app ::&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://codesandbox.io/p/sandbox/laughing-feather-86lksg" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;codesandbox.io&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Below are the screenshots ::&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%2Fgb5kmdl6rxbcbidp3pyd.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%2Fgb5kmdl6rxbcbidp3pyd.png" alt="Dashboard View"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frss5xdu4c7xqugduf9b3.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%2Frss5xdu4c7xqugduf9b3.png" alt="Add Feedback View"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  KendoReact Components Used
&lt;/h2&gt;

&lt;p&gt;{ Switch } from "@progress/kendo-react-inputs";&lt;br&gt;
{ ListBox } from "@progress/kendo-react-listbox";&lt;br&gt;
{ Dialog, DialogActionsBar } from "@progress/kendo-react-dialogs";&lt;br&gt;
{ DropDownList, MultiSelect } from "@progress/kendo-react-dropdowns";&lt;br&gt;
{ Input } from "@progress/kendo-react-inputs";&lt;br&gt;
{ DatePicker } from "@progress/kendo-react-dateinputs";&lt;br&gt;
{ Button } from "@progress/kendo-react-buttons";&lt;br&gt;
{ Grid, GridColumn, GridToolbar } from "@progress/kendo-react-grid";&lt;/p&gt;

&lt;h2&gt;
  
  
  [Optional: Code Smarter, Not Harder prize category] AI Coding Assistant Usage
&lt;/h2&gt;

&lt;h2&gt;
  
  
  [Optional: RAGs to Riches prize category] Nuclia Integration
&lt;/h2&gt;

</description>
      <category>devchallenge</category>
      <category>kendoreactchallenge</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Showcase on LinkedIn</title>
      <dc:creator>Tanmay Banerjee</dc:creator>
      <pubDate>Tue, 16 Jan 2024 19:49:51 +0000</pubDate>
      <link>https://dev.to/tanmaybanerjee/showcase-on-linkedin-21k2</link>
      <guid>https://dev.to/tanmaybanerjee/showcase-on-linkedin-21k2</guid>
      <description>&lt;p&gt;Would you like to showcase your favorite piece of work on linkedIn ? &lt;/p&gt;

&lt;p&gt;Have a look at the below video and support for more such info!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=MQiypu7kAPE"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linkedin</category>
      <category>showcase</category>
      <category>skills</category>
    </item>
    <item>
      <title>React functional component on change of one of prop value to empty object doesn't re-render / return its JSX</title>
      <dc:creator>Tanmay Banerjee</dc:creator>
      <pubDate>Mon, 07 Jun 2021 12:24:25 +0000</pubDate>
      <link>https://dev.to/tanmaybanerjee/react-functional-component-on-change-of-one-of-prop-value-to-empty-object-doesn-t-re-render-return-its-jsx-2aic</link>
      <guid>https://dev.to/tanmaybanerjee/react-functional-component-on-change-of-one-of-prop-value-to-empty-object-doesn-t-re-render-return-its-jsx-2aic</guid>
      <description>&lt;p&gt;Below is how my component looks like :&lt;/p&gt;

&lt;p&gt;import React, { useEffect } from "react";&lt;br&gt;
import { connect } from "react-redux";&lt;/p&gt;

&lt;p&gt;const createSomeStr = ( someObj, someOtherObj ) =&amp;gt; { &lt;br&gt;
  if ( someObj.someField ) {&lt;br&gt;
    // this has a whole lot of computing to create a string but &lt;br&gt;
    // for this example I am just making it simple &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return someOtherObj.someField + someObj.someField;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;return "";&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;const myFunctionalComponent = ( props ) =&amp;gt; {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect( () =&amp;gt; {
    // this won't get called when someOtherObj is being set to blank.
     console.log( "on change of someOtherObj" );
}, [ someOtherObj ] );

return ( props.arrayOfObjects.map( ( obj, index ) =&amp;gt; {
    return ( &amp;lt;div key={ "mKey"+ index }&amp;gt;
      &amp;lt;div&amp;gt;{ obj.someField }&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{ createSomeStr( obj, props.someOtherObj ) }&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt; )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;})&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;export default connect( {&lt;br&gt;
  arrayOfObjects: state.someReducer.arrayOfObjects,&lt;br&gt;
  someOtherObj: state.someReducer.someOtherObj&lt;br&gt;
}, {} )( myFunctionalComponent );&lt;/p&gt;

&lt;p&gt;// my reducer looks something like this ( it works fine as expected as I can make that out from redux dev tools )&lt;br&gt;
export default function ( state = { someOtherObj }, action ) {&lt;br&gt;
  let newSomeOtherObj = {};&lt;/p&gt;

&lt;p&gt;if ( action.type === "SOME_TYPE" ) {&lt;/p&gt;

&lt;p&gt;newSomeOtherObj = state.someOtherObj;&lt;/p&gt;

&lt;p&gt;delete newSomeOtherObj[ action.payload ];&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;switch( action.type ) {&lt;/p&gt;

&lt;p&gt;case "SOME_TYPE":&lt;br&gt;
  return {&lt;br&gt;
    ...state,&lt;br&gt;
    someOtherObj: newSomeOtherObj&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;default:&lt;br&gt;
    return state;&lt;br&gt;
  }&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;In a functional component I have used two props one as arrayOfObjects and other is an someOtherObj.&lt;/p&gt;

&lt;p&gt;What happens is :: arrayOfObjects get its values on mount, component re-renders with desired results;&lt;/p&gt;

&lt;p&gt;someOtherObj get its object updated with a key on some event, component re-renders with the updated string in the second div;&lt;/p&gt;

&lt;p&gt;someOtherObj get its value updated with a blank object ( verified from redux dev tools ), component doesn't re-render until arrayOfObject gets updated. No clue why it's not re-rendering on second update of someOtherObj ...&lt;/p&gt;

&lt;p&gt;Update1 :: You can find my useEffect and it's comment ... As per me react isn't considering it to be an update event when someOtherObj is being set to blank. I am not getting the reason for such behavior ...&lt;/p&gt;

&lt;p&gt;Update2 :: I did convert the same component using class and the same behavior remains. Can anyone let me know it is how react behaves in such scenarios ? Like for any of the prop object changes to blank object and react doesn't consider it to be an prop update and doesn't gets into update life cycle phase ?&lt;/p&gt;

&lt;p&gt;update3 :: I found a solution to this as to keep a field set for the lifetime of the component.&lt;/p&gt;

&lt;p&gt;So I made these changes to the reducer ...&lt;/p&gt;

&lt;p&gt;export default function ( state = { someOtherObj }, action ) {&lt;br&gt;
  let newSomeOtherObj = { isAnyFieldPresent: false };&lt;/p&gt;

&lt;p&gt;if ( action.type === "SOME_TYPE" ) {&lt;/p&gt;

&lt;p&gt;newSomeOtherObj = {&lt;br&gt;
 ...newSomeOtherObj,&lt;br&gt;
 ...state.someOtherObj&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;delete newSomeOtherObj[ action.payload ];&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;switch( action.type ) {&lt;/p&gt;

&lt;p&gt;case "SOME_TYPE":&lt;br&gt;
  return {&lt;br&gt;
    ...state,&lt;br&gt;
    someOtherObj: newSomeOtherObj&lt;br&gt;
  };&lt;/p&gt;

&lt;p&gt;default:&lt;br&gt;
    return state;&lt;br&gt;
  }&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;Doing this the component is now able to detect all the update to someOtherObj as it never finds that object to be empty.&lt;/p&gt;

&lt;p&gt;But this seems to be a workaround.&lt;/p&gt;

&lt;p&gt;Yet I would Like know why such behavior ? A change is a change being it converting an object to a blank object or just changing the field values of the object and if the component is to detect changes to that object and is to fire update life cycle phase then it should on both scenarios.&lt;/p&gt;

&lt;p&gt;let me know if I am wrong with my understanding or any thing to this issue.&lt;/p&gt;

&lt;p&gt;Thanks and regards, Tanmay.&lt;/p&gt;

</description>
      <category>help</category>
      <category>react</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
