<?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: Vinay P</title>
    <description>The latest articles on DEV Community by Vinay P (@vprsdn).</description>
    <link>https://dev.to/vprsdn</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%2F845140%2Fdbc5e598-62fc-4580-b09e-0c98b4625f7b.png</url>
      <title>DEV Community: Vinay P</title>
      <link>https://dev.to/vprsdn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vprsdn"/>
    <language>en</language>
    <item>
      <title>Accessing Custom Flags from Terminal</title>
      <dc:creator>Vinay P</dc:creator>
      <pubDate>Wed, 21 Dec 2022 16:17:21 +0000</pubDate>
      <link>https://dev.to/vprsdn/accessing-custom-flags-from-terminal-cli</link>
      <guid>https://dev.to/vprsdn/accessing-custom-flags-from-terminal-cli</guid>
      <description>&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React app setup with webpack which can be found &lt;a href="https://github.com/aydotvin/react/tree/main/accessing_terminal_flags" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Two pathways:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Terminal -&amp;gt; webpack -&amp;gt; application logic&lt;/li&gt;
&lt;li&gt;One terminal command to another&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  1. Terminal -&amp;gt; webpack -&amp;gt; application logic
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Overview:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Terminal flag is passed from terminal to webpack file using &lt;code&gt;cross-env&lt;/code&gt; and is set as env variable using &lt;code&gt;webpack.DefinePlugin()&lt;/code&gt; which is accessible via &lt;code&gt;process.env.variableName&lt;/code&gt; while writing logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Syntax:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  - Script command
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"start": "cross-env variable_name_1=$npm_config_&amp;lt;flag_name_1&amp;gt; variable_name_2=$npm_config_&amp;lt;flag_name_2&amp;gt; webpack serve --config ./webpack/webpack.dev.js"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;variable_name_1&lt;/code&gt; - this is the variable that is accessible in the webpack config via &lt;code&gt;process.env.variable_name_1&lt;/code&gt;. Same with &lt;code&gt;variable_name_2&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;flag_name_1&lt;/code&gt; - this is the flag name that has to be entered in the terminal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  - Terminal command
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start --flag_name_1=flagvalue1 --flag_name_2=flagvalue2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;cross-env&lt;/code&gt; npm.&lt;/li&gt;
&lt;li&gt;Add the following script under the &lt;code&gt;package.json&lt;/code&gt; scripts.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"start": "cross-env clientVariable=$npm_config_client themeVariable=$npm_config_theme webpack serve --config ./webpack/webpack.dev.js"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the webpack config file (&lt;code&gt;webpack.common.js&lt;/code&gt;), the flag values will be accessible with &lt;code&gt;process.env.clientVariable&lt;/code&gt; and &lt;code&gt;process.env.themeVariable&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const client = process.env.clientVariable;
const theme = process.env.themeVariable;
console.log("client in common webpack", client);
console.log("theme in common webpack", theme);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now under the plugins, define the variables to be accessed in the application.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new webpack.DefinePlugin({
    "process.env.client": JSON.stringify(client),
    "process.env.theme": JSON.stringify(client),
}),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;These flags can be accessed in the requried components using &lt;code&gt;process.env.client&lt;/code&gt; and &lt;code&gt;process.env.theme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
    return (
        &amp;lt;div className={styles.app}&amp;gt;
            &amp;lt;h2&amp;gt;App Component.&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;
                Environment value terminal flag, Client - &amp;lt;span className={styles.envValue}&amp;gt;{process.env.client}&amp;lt;/span&amp;gt;
            &amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;
                Environment value terminal flag, Theme - &amp;lt;span className={styles.envValue}&amp;gt;{process.env.theme}&amp;lt;/span&amp;gt;
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now enter the following command in terminal and the values will be available.
&lt;code&gt;npm run start --client=clientA --theme=light&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. One terminal command to another
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Overview:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Terminal flag is passed from one terminal command to another script call using &lt;code&gt;cross-env-shell&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;With the &lt;code&gt;cross-env&lt;/code&gt; npm package installed.&lt;/li&gt;
&lt;li&gt;Add the following scripts under the &lt;code&gt;package.json&lt;/code&gt; scripts.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"echoMessage": "cross-env-shell clientVariable=$npm_config_client themeVariable=$npm_config_theme echo \"Hello $clientVariable, theme is $themeVariable\""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"greet": "cross-env clientVariable=$npm_config_client themeVariable=$npm_config_theme npm run echoMessage"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The only difference would be the usage of &lt;code&gt;cross-env-shell&lt;/code&gt; instead of &lt;code&gt;cross-env&lt;/code&gt; to access the entered flag value from the parent command.&lt;/li&gt;
&lt;li&gt;Now enter the following command in terminal.
&lt;code&gt;npm run greet --client=clientA --theme=light&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You would see the following output in the terminal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hello clientA, theme is light&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once &lt;code&gt;greet&lt;/code&gt; script is run, npm configs - &lt;code&gt;client&lt;/code&gt; and &lt;code&gt;theme&lt;/code&gt; will be set and those values can be accessed in other scripts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When &lt;code&gt;echoMessage&lt;/code&gt; is called from &lt;code&gt;greet&lt;/code&gt; script, npm configs - &lt;code&gt;client&lt;/code&gt; and &lt;code&gt;theme&lt;/code&gt; will be assigned to the variables listed for them in the &lt;code&gt;echoMessage&lt;/code&gt; script, i.e, &lt;code&gt;clientVariable&lt;/code&gt; and &lt;code&gt;themeVariable&lt;/code&gt;. These variables can be accessed in the script using &lt;code&gt;$clientVariable&lt;/code&gt; and &lt;code&gt;$themeVariable&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This can be used when certain actions needs to be taken based on the client name or anything similar.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Repo link: &lt;a href="https://github.com/aydotvin/react/tree/main/accessing_terminal_flags" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Reference: &lt;a href="https://www.npmjs.com/package/cross-env" rel="noopener noreferrer"&gt;cross-env&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>webpack</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Drag n Drop Walkthrough in React</title>
      <dc:creator>Vinay P</dc:creator>
      <pubDate>Tue, 20 Dec 2022 11:49:15 +0000</pubDate>
      <link>https://dev.to/vprsdn/react-drag-n-drop-walkthrough-3fnc</link>
      <guid>https://dev.to/vprsdn/react-drag-n-drop-walkthrough-3fnc</guid>
      <description>&lt;ul&gt;
&lt;li&gt;This project demonstrates the concepts to implement a drag and drop functionality.&lt;/li&gt;
&lt;li&gt;It is a simple board with two columns and the cards can be to and from both the columns.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React project setup - &lt;code&gt;npx create-react-app app_name&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Elements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Card.js&lt;/code&gt; - the item that is being dragged from one column to another. Element with green background.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Board.js&lt;/code&gt; - contains the states on which the card is being dropped. Element with blue-ish background&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Steps:
&lt;/h3&gt;

&lt;h5&gt;
  
  
  In &lt;code&gt;Card.js&lt;/code&gt;
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Make the card draggable by setting &lt;code&gt;draggable&lt;/code&gt; attribute on the card to true.&lt;/li&gt;
&lt;li&gt;Store the data of the element in an attribute.&lt;/li&gt;
&lt;li&gt;Set an &lt;code&gt;onDragStart&lt;/code&gt; listener on the card and once it is started, take the card data (from the attribute) and set it to &lt;code&gt;dataTransfer&lt;/code&gt; object of the event using &lt;code&gt;setData&lt;/code&gt; function of &lt;code&gt;dataTransfer&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Card = ({ cardData = {} }) =&amp;gt; {
    const [cardIsBeingDragged, setCardIsBeingDragged] = useState(false);

    const handleOnDragStart = (ev) =&amp;gt; {
        let draggedItemData = ev.target.getAttribute("data_card_json") || "{}";
        ev.dataTransfer.setData("draggedItemData", draggedItemData);
        setCardIsBeingDragged(true); // For styling purpose.
    }

    const handleOnDragEnd = () =&amp;gt; {
        setCardIsBeingDragged(false); // For styling purpose.
        // console.log("drag stopped");
    }

    return (
        &amp;lt;div
            className={`${styles.card} ${cardIsBeingDragged ? styles.reducedOpacity : ""}`}
            data_card_json={JSON.stringify(cardData)}
            draggable
            onDragStart={handleOnDragStart}
            onDragEnd={handleOnDragEnd}
        &amp;gt;
            &amp;lt;h3&amp;gt;{cardData.name}&amp;lt;/h3&amp;gt;
            &amp;lt;h3&amp;gt;State - {cardData.state}&amp;lt;/h3&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  In &lt;code&gt;Board.js&lt;/code&gt;
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Set an &lt;code&gt;onDrop&lt;/code&gt; listener on the element on which the drop happens.

&lt;ul&gt;
&lt;li&gt;Pass a function that will take the card data from &lt;code&gt;dataTransfer&lt;/code&gt; object using &lt;code&gt;getData&lt;/code&gt; function of &lt;code&gt;dataTransfer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Check the initial state of the card data and the newly dragged state and make appropriate changes and set new data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;By defult, browser prevents the &lt;code&gt;drop&lt;/code&gt; events on elements. So &lt;code&gt;onDragOver&lt;/code&gt;, prevent the default behavior using &lt;code&gt;preventDefault()&lt;/code&gt; and &lt;code&gt;stopPropagation()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className={`${styles.columns}`}&amp;gt;
    &amp;lt;div className={`dropTarget`} data_state="A" onDrop={handleOnDrop} onDragOver={handleOnDragOver} onDragEnter={handleOnDragEnter}&amp;gt;
        {cardItems.map((card, index) =&amp;gt; {
            if (card.state === "A") {
                    return &amp;lt;Card key={index} cardData={card} /&amp;gt;;
            }
            return null;
        })}
    &amp;lt;/div&amp;gt;
    &amp;lt;div className={`${styles.state} dropTarget`} data_state="B" onDrop={handleOnDrop} onDragOver={handleOnDragOver} onDragEnter={handleOnDragEnter}&amp;gt;
        {cardItems.map((card, index) =&amp;gt; {
            if (card.state === "B") {
                return &amp;lt;Card key={index} cardData={card} /&amp;gt;;
            }
            return null;
        })} 
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Event handlers:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleOnDrop&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleOnDrop = (ev) =&amp;gt; {
    const dropTarget = ev.target.closest(".dropTarget");
    const droppedState = dropTarget.getAttribute("data_state");
    const draggedItemData = JSON.parse(ev.dataTransfer.getData("draggedItemData"));
    const currentItemState = draggedItemData.state;

    if (droppedState !== null &amp;amp;&amp;amp; currentItemState !== droppedState) {
        //  Update the state of the dragged item if its dropped on a different column.
        updateCardStatus(draggedItemData, droppedState);
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleOnDragOver&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleOnDragOver = (ev) =&amp;gt; {
    ev.stopPropagation();
    ev.preventDefault();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleOnDragEnter&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleOnDragEnter = (ev) =&amp;gt; {
    //  Modify the styles of the container if requried.
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleOnDragEnter&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const updateCardStatus = (itemData, droppedState) =&amp;gt; {
    const newCardItems = cardItems.map((eachCard) =&amp;gt; {
        if (eachCard.id === itemData.id) {
            return { ...eachCard, state: droppedState };
        }
        return eachCard;
    });
    setCardItems(newCardItems);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make an card draggable.&lt;/li&gt;
&lt;li&gt;Once dragged, store the data about the card in &lt;code&gt;dataTransfer&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;Once dropped on the target, check if the card is dropped on a new state (column) or not.&lt;/li&gt;
&lt;li&gt;If it is new state (column), update the card's data in the state, which renders the UI with newly set data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repo link: &lt;a href="https://github.com/aydotvin/react/tree/main/drag_n_drop" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>React Redux Walk-through</title>
      <dc:creator>Vinay P</dc:creator>
      <pubDate>Mon, 23 May 2022 05:48:25 +0000</pubDate>
      <link>https://dev.to/vprsdn/react-redux-walk-through-4il1</link>
      <guid>https://dev.to/vprsdn/react-redux-walk-through-4il1</guid>
      <description>&lt;p&gt;&lt;strong&gt;Redux&lt;/strong&gt; is a &lt;strong&gt;state management tool&lt;/strong&gt; that provides a way to have &lt;strong&gt;all the states of an application in one global place&lt;/strong&gt; instead of having in each components.&lt;/p&gt;




&lt;h4&gt;
  
  
  Prerequisites:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;React project setup - &lt;code&gt;npx create-react-app app_name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Packages - &lt;code&gt;npm i redux react-redux @reduxjs/toolkit&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Methods used:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;import { combineReducers, createStore, applyMiddleware } from "redux";&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;import { Provider, useSelector, useDispatch } from "react-redux";&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;import { configureStore } from "@reduxjs/toolkit";&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  1. combineReducers
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Used to combine multiple reducers and make it one to send it to the store.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reducer = combineReducers({
    userData: userReducer,
    ...
    &amp;lt;more here&amp;gt;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. createStore (deprecated)/configureStore
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;  Used to create a store (redux state) using the combined reducer and also apply any middlewares if required to perform before the actions reaches the reducers.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const store = createStore(reducer, applyMiddleware(thunk, middelware2, middleware3, etc..));    // this is deprecated.
(OR)
const store = configureStore({
    reducer,
    middleware: (getDefaultMiddleware) =&amp;gt; getDefaultMiddleware().concat(middleware1, middleware2, etc...)
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. Provider
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;  This component will wrap around the final component (in index.js) that is added to the DOM.&lt;/li&gt;
&lt;li&gt;  The store is made available to the entire application through this.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ReactDOM.render(
    &amp;lt;Provider store={store}&amp;gt;
        &amp;lt;App&amp;gt;&amp;lt;/App&amp;gt;
    &amp;lt;/Provider&amp;gt;,
    document.getElementById("root")
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  4. useSelector
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;  Used to access the state data from redux state.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
    const userData = useSelector((state) =&amp;gt; state.userData);    //  where userData is the key name given in the combineReducers.
    const userId = userData.userId;

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h3&amp;gt;User id is {userId}&amp;lt;/h3&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  5. useDispatch
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;  Used to dispatch the actions that will inturn modify the state data accordingly.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
    const dispatch = useDispatch();

    const updateUserId = (ev) =&amp;gt; {
        dispatch(setUserId(ev.target.value));   //  action creator
        dispatch({type: "SET_USER_ID", payload: ev.target.value});  //  regular dispatch
    };

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;input type="text" value={userId} onChange={updateUserId} /&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  1. Declare the action type constants.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/state/actionTypes.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const actionTypes = {
    user: {
        SET_NEW_USER: "SET_NEW_USER",
        SET_USER_ID: "SET_USER_ID"
    },
    counter: {
        INCREASE_COUNT: "INCREASE_COUNT",
    },
};
export default actionTypes;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. Declare the reducers.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/state/reducers/counterReducer.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import actionTypes from "../actionTypes";
const counterReducer = (state = 0, action = {}) =&amp;gt; {
    switch (action.type) {
        case actionTypes.counter.INCREASE_COUNT:
            return state + action.payload.count;

        default:
            return state;
    }
};
export default counterReducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;~/src/state/reducers/userReducer.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import actionTypes from "../actionTypes";
const userReducer = (state = { userId: 1, userData: {} }, action = {}) =&amp;gt; {
    switch (action.type) {
        case actionTypes.user.SET_NEW_USER:
            return {
                ...state,
                userData: { ...action.payload },
            };
        case actionTypes.user.SET_USER_ID:
            return {
                ...state,
                userId: action.payload,
            };
        default:
            return state;
    }
};
export default userReducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. Combine the reducers.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/state/reducers/index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { combineReducers } from "redux";
    import userReducer from "./userReducer";
    import counterReducer from "./counterReducer";

    const reducer = combineReducers({
        userData: userReducer,
        countData: counterReducer,
    });
    export default reducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  4. Create the store by passing the combined reducer and the middlewares if any.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/state/store.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//  import { createStore, applyMiddleware } from "redux";
//  import thunk from "redux-thunk";
import { configureStore } from "@reduxjs/toolkit";
import reducer from "./reducers/index";

//  createStore is deprecated..
// const store = createStore(reducer, applyMiddleware(thunk));  

const store = configureStore({
    reducer,
    middleware: (getDefaultMiddleware) =&amp;gt; getDefaultMiddleware(),
});

// To add additional middlewares,
// middleware: (getDefaultMiddleware) =&amp;gt; getDefaultMiddleware().concat(middleware1, middleware2, etc...),  //  thunk is inbuilt in @reduxjs/toolkit

export default store;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  5. Declare the actions as per requirment for the features.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/state/actions/counterActions.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import actionTypes from "../actionTypes";
const increaseCount = (countToIncrease) =&amp;gt; {
    return {
        type: actionTypes.counter.INCREASE_COUNT,
        payload: { count: countToIncrease },
    };
};
export { increaseCount };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;~/src/state/actions/userActions.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "axios";
import actionTypes from "../actionTypes";
const getUser = (userId) =&amp;gt; {
    return async (dispatchMethod, getState) =&amp;gt; {
        const userResponse = await axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`);
        const userData = await userResponse.data;
        dispatchMethod({ type: actionTypes.user.SET_NEW_USER, payload: userData });
        return userData;
    };
};

const setUserId = (userId) =&amp;gt; {
    return {
        type: actionTypes.user.SET_USER_ID,
        payload: userId,
    };
};

export { getUser, setUserId };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  6. Implement the features and dispatch the actions as required.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/components/counter/Counter.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useSelector, useDispatch } from "react-redux";
import { increaseCount } from "./../../state/actions/counterActions";

const Counter = () =&amp;gt; {
    const counterData = useSelector((state) =&amp;gt; state.counterData);
    const dispatch = useDispatch();
    const handleIncreaseCount = (count = 1) =&amp;gt; {
        dispatch(increaseCount(count));
    };

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h2&amp;gt;Counter&amp;lt;/h2&amp;gt;
            &amp;lt;h3&amp;gt;{counterData}&amp;lt;/h3&amp;gt;
            &amp;lt;button
                onClick={() =&amp;gt; {
                    handleIncreaseCount(1);
                }}
                style={{ marginRight: "10px" }}
            &amp;gt;
                Increase count by 1
            &amp;lt;/button&amp;gt;
            &amp;lt;button
                onClick={() =&amp;gt; {
                    handleIncreaseCount(5);
                }}
            &amp;gt;
                Increase count by 5
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;~/src/App.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";

import { getUser, setUserId } from "./state/actions/userActions";

import Profile from "./components/user/Profile";
import Counter from "./components/counter/Counter";

const App = () =&amp;gt; {
    const userData = useSelector((state) =&amp;gt; state.userData);
    const userId = userData.userId;
    const [showLoader, setShowLoader] = useState(false);
    const dispatch = useDispatch();

    const getUserInfo = () =&amp;gt; {
        setShowLoader(true);
        dispatch(getUser(userId))
            .then((res) =&amp;gt; {
                console.log(res);
            })
            .catch((err) =&amp;gt; {
                console.log(err);
            })
            .finally(() =&amp;gt; {
                setShowLoader(false);
            });
    };

    const updateUserId = (ev) =&amp;gt; {
        dispatch(setUserId(ev.target.value));
    };

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;input type="text" value={userId} onChange={updateUserId} /&amp;gt;
            &amp;lt;h3&amp;gt;User id is {userId}&amp;lt;/h3&amp;gt;
            &amp;lt;button onClick={getUserInfo}&amp;gt;Get user info&amp;lt;/button&amp;gt;
            &amp;lt;br /&amp;gt;
            {showLoader ? "loading..." : &amp;lt;Profile&amp;gt;&amp;lt;/Profile&amp;gt;}
            &amp;lt;hr /&amp;gt;
            &amp;lt;Counter&amp;gt;&amp;lt;/Counter&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  7. Wrap the whole application with the provider and pass the store as a prop.
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;~/src/index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import ReactDOM from "react-dom";
    import App from "./App";
    import { Provider } from "react-redux";
    import store from "./state/store";
    ReactDOM.render(
        &amp;lt;Provider store={store}&amp;gt;
            &amp;lt;App&amp;gt;&amp;lt;/App&amp;gt;
        &amp;lt;/Provider&amp;gt;,
        document.getElementById("root")
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Persisting redux state on refresh
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  This requires changes in the following two files,&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;~/src/state/store.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;~/src/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  1. &lt;code&gt;npm i redux-persist&lt;/code&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  2. &lt;code&gt;~/src/state/store.js&lt;/code&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    //  NEW LINES START
    import { persistStore, persistReducer } from "redux-persist";
    import storage from "redux-persist/lib/storage";

    //  Setup persist config and persist reducer
    const persistConfig = {
        key: "persisted_state_data",
        storage,
    };
    const persistedReducer = persistReducer(persistConfig, reducer);
    //  NEW LINES END

    //  UPDATED LINE START
    //  Pass this persisted reducer to the store configurator and disable the serializableCheck.
    const store = configureStore({
        reducer: persistedReducer,
        middleware: (getDefaultMiddleware) =&amp;gt; getDefaultMiddleware({
            serializableCheck: false,
        }),
    });
     //  UPDATED LINE END

    //  NEW LINE START
    // Create a persisted store along with the normal store and export both.
    const persistor = persistStore(store);
    //  NEW LINE END

    //  UPDATED LINE START
    export { persistor, store };
    //  UPDATED LINE END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. &lt;code&gt;~/src/index.js&lt;/code&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//  Import persisted store and the regular store.
import { persistor, store } from "./state/store";
import { PersistGate } from "redux-persist/integration/react";

//  Within the redux provider wrap the app with the PersistGate component and pass the persistStore.
ReactDOM.render(
    &amp;lt;Provider store={store}&amp;gt;
        &amp;lt;PersistGate persistor={persistor}&amp;gt;
            &amp;lt;App&amp;gt;&amp;lt;/App&amp;gt;
        &amp;lt;/PersistGate&amp;gt;
    &amp;lt;/Provider&amp;gt;,
    document.getElementById("root")
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;









&lt;p&gt;Repo link: &lt;a href="https://github.com/aydotvin/template_redux" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  P.S.
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;  First post 🙏&lt;/li&gt;
&lt;li&gt;  Hopefully it saves someone a few hours of R&amp;amp;D.&lt;/li&gt;
&lt;/ul&gt;

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