<?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: Khaled Ben Yahya</title>
    <description>The latest articles on DEV Community by Khaled Ben Yahya (@khaledbenyahya_).</description>
    <link>https://dev.to/khaledbenyahya_</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%2F1129133%2F8e8e761c-c5a6-4cfd-80d6-09a6ce7ac252.jpg</url>
      <title>DEV Community: Khaled Ben Yahya</title>
      <link>https://dev.to/khaledbenyahya_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khaledbenyahya_"/>
    <language>en</language>
    <item>
      <title>Supercharge Redux with ‘immer’: Using ‘immer’ to update Redux state in a more readable and safer way.</title>
      <dc:creator>Khaled Ben Yahya</dc:creator>
      <pubDate>Tue, 22 Aug 2023 12:41:29 +0000</pubDate>
      <link>https://dev.to/khaledbenyahya_/supercharge-redux-with-immer-using-immer-to-update-redux-state-in-a-more-readable-and-safer-way-2g19</link>
      <guid>https://dev.to/khaledbenyahya_/supercharge-redux-with-immer-using-immer-to-update-redux-state-in-a-more-readable-and-safer-way-2g19</guid>
      <description>&lt;p&gt;Using immer in Redux reducers can significantly improve the readability and maintainability of your code, while also helping to avoid potential issues that can arise when not using it. Here are some reasons why using immer is considered better:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oqn9oopC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3h977b5303s52o9ql2du.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oqn9oopC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3h977b5303s52o9ql2du.png" alt="Image description" width="800" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1/Immutability Made Simple: One of the core principles of Redux is immutability, which helps ensure predictability and efficient state management. While the old way of updating the state using spread operators &lt;code&gt;({ ...state, counter: state.counter + 1 })&lt;/code&gt; achieves immutability, it can become cumbersome and error-prone, especially when dealing with nested objects and arrays. immer simplifies the process by allowing you to directly modify a draft state while maintaining immutability.&lt;/p&gt;

&lt;p&gt;2/Clarity and Readability: With immer, your code becomes more concise and expressive. The syntax closely resembles that of mutable updates, making it easier to understand what changes are being made to the state. This is particularly helpful when dealing with complex state structures or a series of updates.&lt;/p&gt;

&lt;p&gt;3/No Need for Manual Cloning: When using the traditional approach, you need to manually clone nested objects and arrays to ensure immutability. With immer, you can update nested properties directly within the draft state, saving you from writing repetitive cloning code.&lt;/p&gt;

&lt;p&gt;4/Avoiding Accidental Mutations: Without immer, it's possible to accidentally mutate the state, leading to unpredictable behavior in your application. With immer, you work on a draft state that is a copy of the original state, so you don't have to worry about unintentional mutations.&lt;/p&gt;

&lt;p&gt;5/Performance Optimization: immer is designed to optimize the performance of updates. It creates a proxy layer over the draft state and applies updates lazily, only modifying the necessary parts of the state when changes are made.&lt;/p&gt;

&lt;p&gt;6/Simplifying Complex Reducers: Reducers that handle complex state structures or deeply nested objects can become difficult to manage using the traditional approach. immer simplifies these scenarios by allowing you to directly modify the draft state in a natural and intuitive way.&lt;/p&gt;

&lt;p&gt;While not using immer might not cause immediate issues, as your application grows, the codebase becomes more complex, and more developers get involved, the risk of introducing accidental mutations and decreasing code readability increases. Using immer helps mitigate these risks and leads to cleaner, more maintainable Redux code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Convert your Existing React js App to Android App Using the Ionic Capacitor</title>
      <dc:creator>Khaled Ben Yahya</dc:creator>
      <pubDate>Sun, 30 Jul 2023 06:40:14 +0000</pubDate>
      <link>https://dev.to/khaledbenyahya_/convert-your-existing-react-js-app-to-android-app-using-the-ionic-capacitor-4g61</link>
      <guid>https://dev.to/khaledbenyahya_/convert-your-existing-react-js-app-to-android-app-using-the-ionic-capacitor-4g61</guid>
      <description>&lt;p&gt;Today I will show the easiest and simple way I’ve found to convert your existing React js app to an android app using ionic capacitor.&lt;/p&gt;

&lt;p&gt;What is Capacitor? According to documentation:&lt;/p&gt;

&lt;p&gt;Capacitor is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, Electron, and the web. We call these apps “Native Progressive Web Apps” and they represent the next evolution beyond Hybrid apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existing React App&lt;/li&gt;
&lt;li&gt;Ionic&lt;/li&gt;
&lt;li&gt;Android Studio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, go to the root of your existing react app and create a file &lt;code&gt;capacitor.config.json&lt;/code&gt; and inside that put the below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "appId": "io.ionic.nameofyourapp",
  "appName": "nameofyourapp",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "build",
  "cordova": {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now create another file name &lt;code&gt;ionic.config.json&lt;/code&gt; and inside that insert the below code.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "nameofyourapp",
  "integrations": {
    "capacitor": {}
  },
  "type": "react"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: replace &lt;code&gt;nameofyourapp&lt;/code&gt; in both files with the name of your app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now we need to build our react project. To build your react app open your terminal to the root of the project and run the below-mentioned command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: this will create the build folder in your root project and the name of the folder should match the &lt;code&gt;webDir&lt;/code&gt; name inside &lt;code&gt;capacitor.config.json&lt;/code&gt; file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now we will install ionic globally in our machine. To install ionic globally in your machine open your terminal and run the below command.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @ionic/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now install the capacitor core in our project.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @capacitor/core --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now install the capacitor CLI.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -D @capacitor/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After that, we will first create an android app with our existing react app.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ionic capacitor add android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create the android folder in your root project and install all the required dependencies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now run the below command to launch your android project on Android Studio.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx cap open android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait some time and then it will ask you to update the Gradle. Just update the Gradle to the latest version and run the project in the emulator. You can also connect your mobile to run the project live on your mobile phone.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now open the build menu from the android studio and build your &lt;code&gt;apk&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>android</category>
      <category>react</category>
      <category>ionic</category>
    </item>
    <item>
      <title>Redux for State Management</title>
      <dc:creator>Khaled Ben Yahya</dc:creator>
      <pubDate>Sun, 30 Jul 2023 06:31:57 +0000</pubDate>
      <link>https://dev.to/khaledbenyahya_/redux-for-state-management-3pc4</link>
      <guid>https://dev.to/khaledbenyahya_/redux-for-state-management-3pc4</guid>
      <description>&lt;p&gt;Redux is a predictable state container for JavaScript applications that can help you manage your application’s global state in a more organized and maintainable way. The key concepts of Redux are the store, reducers, actions, and dispatch.&lt;/p&gt;

&lt;p&gt;Store: The store is the single source of truth for your application’s state. It’s a plain JavaScript object that holds all of the application’s state data. The store is created using the &lt;code&gt;createStore&lt;/code&gt; function from the Redux library, and it's typically created at the top-level of the application.&lt;/p&gt;

&lt;p&gt;Reducers: Reducers are pure functions that take the current state and an action, and return a new state based on the action. Reducers are responsible for updating the store’s state in response to actions dispatched by the application. The state returned from the reducer must be a new object, and not a mutated version of the previous state. Here’s an example of a simple reducer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the reducer updates the state based on two actions: &lt;code&gt;INCREMENT&lt;/code&gt; and &lt;code&gt;DECREMENT&lt;/code&gt;. When an &lt;code&gt;INCREMENT&lt;/code&gt; action is dispatched, the reducer returns a new object with the count property incremented by 1. Similarly, when a &lt;code&gt;DECREMENT&lt;/code&gt; action is dispatched, the reducer returns a new object with the count property decremented by 1.&lt;/p&gt;

&lt;p&gt;Actions: Actions are plain JavaScript objects that describe changes to the application’s state. They must have a &lt;code&gt;type&lt;/code&gt; property that describes the type of action being performed, and can also include any additional data needed to perform the action. Actions are typically created using action creator functions, which are functions that return the action object. Here's an example of an action creator function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function increment() {
  return { type: 'INCREMENT' };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;increment&lt;/code&gt; function returns an action object with a type of &lt;code&gt;INCREMENT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dispatch: Dispatch is the function used to send actions to the store. When an action is dispatched, the store calls the reducers with the current state and the action, and the reducers return the new state. The store then updates its state with the new state returned by the reducers. Dispatch is typically called from within components or other parts of the application that need to update the state. Here’s an example of how to use dispatch to update the count:&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 } from 'redux';
import counterReducer from './counterReducer';

const store = createStore(counterReducer);
store.dispatch({ type: 'INCREMENT' });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;createStore&lt;/code&gt; function creates a new store using the &lt;code&gt;counterReducer&lt;/code&gt;. Then, the &lt;code&gt;dispatch&lt;/code&gt; function is used to send an &lt;code&gt;INCREMENT&lt;/code&gt; action to the store, which updates the count in the store's state.&lt;/p&gt;

&lt;p&gt;One of the benefits of using Redux is that it can simplify your application’s architecture and make it more testable and maintainable. By keeping all of your state in a single, centralized location, you can easily reason about changes to your data over time. Additionally, because Redux relies on pure functions and plain JavaScript objects, it’s easy to test and debug your code.&lt;/p&gt;

&lt;p&gt;Testability is another sweet key feature of using Redux is that it makes your application more testable. Since your state management is centralized and predictable, it becomes easier to write tests that ensure your application is behaving as expected. By writing tests for your actions and reducers, you can be confident that your state changes are working correctly and that you’re not introducing regressions as you add new features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe('incrementCounter', () =&amp;gt; {
  it('should increment the counter by 1', () =&amp;gt; {
    const initialState = { count: 0 };
    const action = { type: 'INCREMENT_COUNTER' };
    const newState = reducer(initialState, action);
    expect(newState.count).toEqual(1);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above defines a test for the &lt;code&gt;incrementCounter&lt;/code&gt; action using the Jest testing framework. The test sets up an initial state, dispatches the action, and expects the new state to have a count of 1. This test demonstrates how Redux makes it easy to test individual actions and their effects on the state of the application.&lt;/p&gt;

&lt;p&gt;While Redux is a powerful tool, it may not be the best choice for every project. For example, if you have a small application with simple state management needs, you might be better off using &lt;a href="https://legacy.reactjs.org/docs/context.html"&gt;React Context&lt;/a&gt; or another simpler solution like &lt;a href="https://docs.pmnd.rs/zustand/getting-started/introduction"&gt;Zustand&lt;/a&gt; which I’m going to using in one of my upcoming projects. It all comes down to your project’s use cases and specificities.&lt;/p&gt;

&lt;p&gt;Finally I highly recommend reading the &lt;a href="https://redux.js.org/tutorials/essentials/part-1-overview-concepts"&gt;Redux&lt;/a&gt; documentation to get started and gradually go in depth in each concept. It definitely helped me have a better understanding quicker than watching Youtube tutorials about it and also to write this article. I decided to write this to keep it as a reference for me so hopefully you find it useful as well. Have a good read!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Effectively Remove .env File from Git Repo/History</title>
      <dc:creator>Khaled Ben Yahya</dc:creator>
      <pubDate>Sun, 30 Jul 2023 06:27:22 +0000</pubDate>
      <link>https://dev.to/khaledbenyahya_/how-to-effectively-remove-env-file-from-git-repohistory-1idi</link>
      <guid>https://dev.to/khaledbenyahya_/how-to-effectively-remove-env-file-from-git-repohistory-1idi</guid>
      <description>&lt;p&gt;The .env file is typically located in the root directory of a project and is not committed to version control systems, such as Git. Instead, it is used to store sensitive information, such as database credentials, API keys, and passwords, which should not be publicly visible. By using an .env file, developers can keep their code and configuration separate, making it easier to maintain and deploy applications.&lt;/p&gt;

&lt;p&gt;You can check the Youtube tutorial I created &lt;a href="https://www.youtube.com/watch?v=B3y-eH2Tkp8"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if you’ve made a mistake like me and forgot to add “.env” to ‘.gitignore’ before pushing your code to your repository, you can follow these few simple steps to undo the catastrophe. 😅 We’re going to remove it not only from our git repository but most importantly from Git history as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WPn_4-63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m1ba01r299yl89dpmb44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WPn_4-63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m1ba01r299yl89dpmb44.png" alt="Image description" width="720" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Removing the file right away&lt;br&gt;
The best thing to do now is to remove the file right away and add it to your .gitignore file.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X3d1GE7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhdzql9pvh9qqvsmpd4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X3d1GE7U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhdzql9pvh9qqvsmpd4i.png" alt="Image description" width="720" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, the .gitignore file doesn't untrack already committed changes. So how can we fix this?&lt;/p&gt;

&lt;p&gt;You can remove a file from Git by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rm -r --cached .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we then push this change, you will see that the file is gone in GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cg3oXfk2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yy9ipo9w6hv58ftudzwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cg3oXfk2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yy9ipo9w6hv58ftudzwg.png" alt="Image description" width="720" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this didn’t completely solve our issue. If we look at our Git history, we can still find the file and expose the secrets!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8TxSjwLX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0t8hoe35a2si01jon40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8TxSjwLX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0t8hoe35a2si01jon40.png" alt="Image description" width="720" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To remove the file altogether, we can use the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch .env" HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get some warnings about this messing up your history as this goes through your whole history and 100% removes its existence. To push this, you have to run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push --force
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we look at our history, we can still see the commits that include this .env file, but the content is empty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xeHzG3hC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2gh2ydshwh5w5064ghj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xeHzG3hC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2gh2ydshwh5w5064ghj.png" alt="Image description" width="720" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Few, thanks for having our back Git!&lt;/p&gt;

</description>
      <category>github</category>
      <category>env</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
