<?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: Ashish Ranjan</title>
    <description>The latest articles on DEV Community by Ashish Ranjan (@ashish_r).</description>
    <link>https://dev.to/ashish_r</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%2F628775%2Ffc0a19c7-1540-4a87-9895-1c6cdf74b2ee.jpg</url>
      <title>DEV Community: Ashish Ranjan</title>
      <link>https://dev.to/ashish_r</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashish_r"/>
    <language>en</language>
    <item>
      <title>Unlocking Success in Problem Solving: Start with the Problem Statement!</title>
      <dc:creator>Ashish Ranjan</dc:creator>
      <pubDate>Mon, 11 Sep 2023 16:18:52 +0000</pubDate>
      <link>https://dev.to/ashish_r/unlocking-success-in-problem-solving-start-with-the-problem-statement-48ke</link>
      <guid>https://dev.to/ashish_r/unlocking-success-in-problem-solving-start-with-the-problem-statement-48ke</guid>
      <description>&lt;p&gt;In the world of development, it's easy to dive headfirst into solving issues. However, before we solve any issue, we should identify the Problem statement clearly and accurately. This is often a step when overlooked or done poorly, leads to wasted time and resources.&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%2Fvvqkiqsyj5r7re481j6e.jpeg" 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%2Fvvqkiqsyj5r7re481j6e.jpeg" alt="What's your problem meme image" width="512" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem statement
&lt;/h2&gt;

&lt;p&gt;As a developer, I often see people misinterpret issues as problem statements. This can lead to solutions that are not effective or even counterproductive. We've all been there, facing an issue, and thinking that the problem statement is simply a feature not working correctly. But wait, there's more to it!&lt;br&gt;
The feature not working correctly is not the actual problem statement; it's just the issue that needs fixing. We should collect some basic info like criticality and identify the problem statement to work upon, which can be like &lt;em&gt;we need to hotfix this issue&lt;/em&gt; or &lt;em&gt;we need to identify the root cause and fix the issue&lt;/em&gt;. The approach to both the problem statements can be very different.&lt;/p&gt;

&lt;p&gt;You can try answering these questions to phrase the core problem statement to work on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the issue?&lt;/li&gt;
&lt;li&gt;Who is affected by the issue?&lt;/li&gt;
&lt;li&gt;What is the importance?&lt;/li&gt;
&lt;li&gt;What are the consequences?&lt;/li&gt;
&lt;li&gt;What are the desired outcomes?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why is this important?
&lt;/h2&gt;

&lt;p&gt;The approach to problem-solving can vary dramatically based on the problem statement. Whether it's a POC, planning of architecture, or process design, understanding the problem statement is a game-changer. When you know the problem, you can start thinking about how to solve it. This can help you narrow down the options and choose the best solution for your needs.&lt;/p&gt;

&lt;p&gt;It's important to remember that there is no one-size-fits-all solution to every problem. We have countless ways, tools, and frameworks at our disposal to solve problems. However, blindly following what others are doing isn't the best strategy. Instead, align the pros and cons of available options with your specific problem statement. Give weightage to the pointers that fit your problem. The best solution will vary depending on the specific problem statement.&lt;/p&gt;

&lt;p&gt;Some additional thoughts on the importance of identifying the problem statement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can help you avoid wasting time and resources on solutions not addressing the core problem.&lt;/li&gt;
&lt;li&gt;It can help you get buy-in from stakeholders, as they will be more likely to support a solution that they understand and believe is necessary.&lt;/li&gt;
&lt;li&gt;It can help you identify the right people to be involved in problem-solving.&lt;/li&gt;
&lt;li&gt;It can help you track your progress and measure the success metrics of your solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're facing a problem, I encourage you to take the time to identify the problem statement first. By taking the time to identify the problem statement, you can increase your chances of solving the problem.&lt;/p&gt;

</description>
      <category>problemsolving</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How to access a private S3 bucket via Cloudflare</title>
      <dc:creator>Ashish Ranjan</dc:creator>
      <pubDate>Tue, 01 Aug 2023 20:09:39 +0000</pubDate>
      <link>https://dev.to/ashish_r/how-to-access-a-private-s3-bucket-via-cloudflare-2nc5</link>
      <guid>https://dev.to/ashish_r/how-to-access-a-private-s3-bucket-via-cloudflare-2nc5</guid>
      <description>&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%2Farozmwdfodr92apayawz.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%2Farozmwdfodr92apayawz.png" alt="Hero Image Cloudflare + S3" width="800" height="247"&gt;&lt;/a&gt;&lt;br&gt;
In this blog post, we'll explore how to access a private S3 bucket via Cloudflare. Most of the tutorials on the internet suggest that you need to enable static hosting on your S3 bucket and use the same name for your bucket and your domain. For example, if your domain is &lt;code&gt;example.com&lt;/code&gt;, your bucket name should be &lt;code&gt;example.com&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;However, this approach has some drawbacks. Amazon S3 website endpoints do not support HTTPS. Using the same name for your bucket and your domain is not always possible or desirable. Bucket names have to be unique across all of AWS, so you might not get the name you want. Also, you might want to map multiple domains to the same bucket, or use an existing bucket with a different domain name.&lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;In this demo, I will show you how to access a private S3 bucket with a different name than your domain via Cloudflare. Let’s assume that we have a bucket named &lt;code&gt;test-bucket&lt;/code&gt; in the &lt;code&gt;eu-central-1&lt;/code&gt; region, and we want to map it to our domain &lt;code&gt;test.ashish.link&lt;/code&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%2Fh4lip2mbzclk7f2x97hv.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%2Fh4lip2mbzclk7f2x97hv.png" alt="Cloudflare dashboard to add CNAME records" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Add a CNAME record on Cloudflare
&lt;/h3&gt;

&lt;p&gt;The first step is to add a CNAME record on Cloudflare that points to the S3 endpoint of our bucket. The S3 endpoint has the format &lt;code&gt;&amp;lt;bucket-name&amp;gt;.s3.&amp;lt;region&amp;gt;.amazonaws.com&lt;/code&gt;. In our case, it is &lt;code&gt;test-bucket.s3.eu-central-1.amazonaws.com&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Add a bucket policy for Cloudflare IPs
&lt;/h3&gt;

&lt;p&gt;The second step is to add a bucket policy on our S3 bucket that allows Cloudflare IPs to access our objects. You can find the list of Cloudflare IPs on their website. The bucket policy should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFlareIP",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::test-bucket",
                "arn:aws:s3:::test-bucket/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        &amp;lt;list of ips&amp;gt;
                    ]
                }
            }
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This policy grants read access to our bucket and its objects only to the requests that come from Cloudflare IPs. You can find the list of cloudflare IPs from &lt;a href="https://www.cloudflare.com/ips/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Set a Host header override on Cloudflare
&lt;/h3&gt;

&lt;p&gt;The final step is to set a Host header override on Cloudflare that tells S3 which bucket we want to access. By default, S3 uses the Host header of the request to determine the bucket name. For example, if we request &lt;code&gt;example.com/image&lt;/code&gt;.jpg, S3 will look for a bucket named &lt;code&gt;example.com&lt;/code&gt;. However, since our bucket has a different name, we need to override this behavior and tell S3 to use &lt;code&gt;test-bucket.s3.eu-central-1.amazonaws.com&lt;/code&gt;as the Host header instead.&lt;br&gt;
To do this, we need to create a &lt;em&gt;Origin rule&lt;/em&gt; on Cloudflare that sets the Host header override as follows:&lt;br&gt;
This origin rule tells Cloudflare to forward all requests for &lt;code&gt;test.ashish.link/*&lt;/code&gt; to our S3 endpoint with the correct Host header.&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%2Fa28qaxl6s6ay8dlwbjn0.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%2Fa28qaxl6s6ay8dlwbjn0.png" alt="Cloudflare dashboard to add origin rules" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;p&gt;By following these steps, you can successfully access a private S3 bucket via Cloudflare, regardless of whether your bucket name matches your domain name or not. This setup allows you to securely and efficiently serve your assets while maximizing control over access.&lt;/p&gt;

&lt;p&gt;I hope you found this post helpful. If you have any questions or feedback, please leave a comment below.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>aws</category>
      <category>s3</category>
    </item>
    <item>
      <title>Modular Ducks - A design pattern for scalable redux architecture</title>
      <dc:creator>Ashish Ranjan</dc:creator>
      <pubDate>Mon, 10 May 2021 17:30:29 +0000</pubDate>
      <link>https://dev.to/ashish_r/modular-ducks-a-design-pattern-for-scalable-redux-architecture-4dna</link>
      <guid>https://dev.to/ashish_r/modular-ducks-a-design-pattern-for-scalable-redux-architecture-4dna</guid>
      <description>&lt;p&gt;The Redux library is highly unopinionated. It lets us decide everything from store set-up and its contents to reducers. This is good because it gives us the flexibility to set it up as per the project requirements, but this flexibility is not always needed. We have to figure out the architecture ourselves, which is not an easy task.&lt;/p&gt;

&lt;p&gt;I have worked with many different redux patterns and architectures, and I have found that none of the redux patterns are perfectly ideal. The ducks-pattern is prone to a circular dependency. The traditional folder-based approach requires you to separate actions, reducers, selectors, etc into multiple files that become cumbersome while developing and refactoring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://redux-toolkit.js.org/" rel="noopener noreferrer"&gt;Redux toolkit&lt;/a&gt; provides an opinionated wrapper around redux and lets us do more with less code. But, the issue with the Redux toolkit is that the project structure becomes similar to ducks and is prone to a circular dependency. Redux toolkit has already warned us of this issue &lt;a href="https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In this article, I am sharing my approach for the architecture with Redux toolkit, which is circular dependency safe, and also handles refactoring with ease.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Let's start with the important redux components in the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break your redux store based on the features of the app. With the Redux toolkit, we can use the &lt;code&gt;createSlice&lt;/code&gt; API to create actions and reducers for an individual slice. &lt;/li&gt;
&lt;li&gt;One thing to keep in mind is no two slices should import from one another. There can be a case when we might have to trigger reducers in two slices for one action. In that case, instead of importing action from one slice to another, create a common action in a separate file using &lt;code&gt;createAction&lt;/code&gt; and register this in both the slices with &lt;code&gt;extraReducers&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Export a constant key from the slice file to be used in the &lt;code&gt;combineReducers&lt;/code&gt; to combine the reducers. Keeping the constant key in a slice file makes the store structure more predictable.&lt;/li&gt;
&lt;li&gt; Keep selectors for all the keys of a slice file in the same slice file. You can also create separate selector files, but keeping them in the slice file makes refactoring a little easier. You can also use &lt;code&gt;createGlobalStateSelector&lt;/code&gt; an &lt;a href="//npmjs.com/package/create-global-state-selector"&gt;ultra-light npm library&lt;/a&gt; to generate global state selectors from the local slice selectors. This approach reduces the refactoring efforts by quite a lot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Actions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Based on the project structure we can have multiple common action files which will use &lt;code&gt;createAction&lt;/code&gt; to export actions that can be used in multiple slices.&lt;/li&gt;
&lt;li&gt;Common action files should not import from any other file (with redux components) in the project directory.&lt;/li&gt;
&lt;li&gt;Common actions can be used inside slices, thunks, or our components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Selectors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just like common actions, we might need selectors from different slices to combine them into one selector (e.g. using &lt;code&gt;createSelector&lt;/code&gt; to create a selector based on multiple selectors in different slices).&lt;/li&gt;
&lt;li&gt;Keeping combined selectors of two different slices outside the slice file in a different selector file avoids the circular dependency issue.&lt;/li&gt;
&lt;li&gt;Common selectors file will import selectors from the slices file and will export combined selectors to be used inside thunks or components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Thunks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thunk actions (or any redux middleware functions) should not be kept in the slice file. Thunks have access to the global state (with &lt;code&gt;getState&lt;/code&gt;) and it might have to dispatch actions to multiple slices.&lt;/li&gt;
&lt;li&gt;You can create multiple files for thunk actions (it is always better to have multiple files than having one giant file). This can also be divided based on the features.&lt;/li&gt;
&lt;li&gt;Thunk action files can import from slice files (actions and selectors), common action files, and common selector files. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Import diagram
&lt;/h3&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%2Fafv23dd2964ri4rpsxsy.jpeg" 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%2Fafv23dd2964ri4rpsxsy.jpeg" alt="redux import diagram" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Code
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// personalDetailsSlice.js

import { createSlice } from '@reduxjs/toolkit';
import createGlobalStateSelector from 'create-global-state-selector';
import { clearData } from './commonActions';

export const sliceKey = 'personalDetails';
const initialState = {
  name: 'Ashish',
  age: '26',
  isEligibleToDrink: false
};

const { actions, reducer } = createSlice({
  name: sliceKey,
  initialState,
  reducers: {
    setName(state, { payload }) {
      state.name = payload;
    },
    setAge(state, { payload }) {
      state.age = payload;
    },
    setDrinkingEligibilityBasedOnAge(state) {
      state.isEligibleToDrink = selectLocalAge(state) &amp;gt;= 18;
    }
  },
  extraReducers: {
    [clearData]: (state) =&amp;gt; {
      state.isEligibleToDrink = null;
      state.age = null;
      state.name = null;
    }
  }
});

function selectLocalName(state) {
  return state.name;
}
function selectLocalAge(state) {
  return state.age;
}
function selectLocalIsEligibleToDrink(state) {
  return state.isEligibleToDrink;
}

export default reducer;
export const { setName, setAge, setDrinkingEligibilityBasedOnAge } = actions;

export const { selectName, selectAge, selectIsEligibleToDrink } = createGlobalStateSelector(
  {
    selectName: selectLocalName,
    selectAge: selectLocalAge,
    selectIsEligibleToDrink: selectLocalIsEligibleToDrink
  },
  sliceKey
);
&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;// educationalDetailsSlice.js

import { createSlice } from '@reduxjs/toolkit';
import createGlobalStateSelector from 'create-global-state-selector';
import { clearData } from './commonActions';

export const sliceKey = 'educationalDetails';
const initialState = {
  qualification: 'engineering'
};

const { actions, reducer } = createSlice({
  name: sliceKey,
  initialState,
  reducers: {
    setQualification(state, { payload }) {
      state.qualification = payload;
    }
  },
  extraReducers: {
    [clearData]: (state) =&amp;gt; {
      state.qualification = null;
    }
  }
});

function selectLocalQualification(state) {
  return state.qualification;
}

export default reducer;
export const { setQualification } = actions;

export const { selectQualification } = createGlobalStateSelector(
  { selectQualification: selectLocalQualification },
  sliceKey
);
&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;// commonActions.js

import { createAction } from '@reduxjs/toolkit';

export const clearData = createAction('detail/clear');
&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;// commonSelectors.js

import { createSelector } from '@reduxjs/toolkit';
import { selectAge } from './personalDetailsSlice';
import { selectQualification } from './educationalDetailsSlice';

export const selectIsEligibleToWork = createSelector(
  selectAge,
  selectQualification,
  (age, qualification) =&amp;gt; age &amp;gt;= 18 &amp;amp;&amp;amp; qualification === 'engineering'
);
&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;// thunks.js

import { fetchQualification } from './api';
import { selectName } from './personalDetailsSlice';
import { setQualification } from './educationalDetailsSlice';
import { clearData } from './commonActions';

export const getQualification = () =&amp;gt; (dispatch, getState) =&amp;gt; {
  const state = getState();
  const name = selectName(state);
  fetchQualification(name)
    .then(({ qualification }) =&amp;gt; dispatch(setQualification(qualification)))
    .catch(() =&amp;gt; dispatch(clearData()));
};
&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;// store.js

import { createStore, combineReducers } from 'redux';
import personalDetailsReducer, { sliceKey as personalDetailsSliceKey } from './personalDetailsSlice';
import educationalDetailsReducer, { sliceKey as educationalDetailsSliceKey } from './educationalDetailsSlice';

const reducer = combineReducers({
  [personalDetailsSliceKey]: personalDetailsReducer, // 'personalDetails'
  [educationalDetailsSliceKey]: educationalDetailsReducer // 'educationalDetails'
});
const store = createStore(reducer);
export default store;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above example can scale well for large-scale projects. &lt;strong&gt;Pro-tip:&lt;/strong&gt; Never import store directly anywhere except the root component file which passes store data to its child components with &lt;code&gt;Provider&lt;/code&gt;. Use redux middlewares (like redux-thunk) when you need to access store data outside your component.&lt;/p&gt;

&lt;p&gt;If you are worried about implementing the import rules in a large size project, check out the &lt;a href="https://www.npmjs.com/package/dependency-cruiser" rel="noopener noreferrer"&gt;Dependency cruiser&lt;/a&gt; library.&lt;/p&gt;




&lt;p&gt;Do share with us your way of creating a modular and scalable redux structure in the comments section.&lt;/p&gt;

&lt;p&gt;If you're confused about anything related to this topic or have any questions, you can comment below or reach out to me on Twitter &lt;a href="https://twitter.com/code_ashish" rel="noopener noreferrer"&gt;@code_ashish&lt;/a&gt;. 🙂&lt;/p&gt;




&lt;h3&gt;
  
  
  Thanks For Reading 😃
&lt;/h3&gt;

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