Categories
Technology

React Native Redux vs  Context API 

React Native Redux vs  Context API 

Redux : 
       Redux is a state management library for JavaScript applications, commonly used with React. It provides a centralized store that holds the entire application’s state, allowing you to manage and access state consistently across the application. 

UseContext : 
        useContext is a React hook that allows components to access and share data across the component tree without the need for props drilling. It works with the Context API, which enables you to create a context and a provider that wraps around parts of your component tree. Components within that subtree can then consume the context directly using useContext, giving them direct access to shared state or data. 

Props drilling :  

          Props drilling is a concept in React where data (props) is passed from a parent component to deeply nested child components. When child components several levels down the component tree need access to the data, you must pass the data through each intermediary component as props, even if those intermediary components don’t actually use the data. 

Problems with Props Drilling: 

  1. Repetitive Code: Every intermediary component must accept and pass along the props, even if it doesn’t use them. 
  1. Maintenance Issues: If you need to add, change, or remove a prop, you must update all components in the path, making the code harder to maintain. 
  1. Scalability: As the app grows, props drilling can make it difficult to manage data, especially when data is needed in many parts of the app. 

useContext and Redux as Solutions to Props Drilling 

Both useContext and Redux help manage global state in React, enabling you to avoid props drilling by providing state to components directly, regardless of their nesting level. 

1. useContext 

The Context API in React allows you to create a context, which provides data directly to any component that needs it, without needing to pass it down through every level in between. 

How it Helps: 

  • With useContext, you can avoid props drilling by wrapping a part of your component tree with a Provider and accessing the data with useContext in any descendant component. 
  • It’s ideal for smaller or medium-sized applications where a piece of data needs to be shared by multiple components, but the app doesn’t require complex state management. 

 
2. Redux 

Redux is a state management library that holds the entire application state in a single store. Components can access and update this state directly, which eliminates the need for props drilling across the application. 

How it Helps: 

  • Redux provides a global store for state, so components can access and update state directly without passing props. 
  • This makes Redux particularly suitable for larger applications with complex state management needs, as it supports middleware for handling asynchronous actions and has powerful debugging tools. 

Both useContext and Redux can help avoid props drilling and make the component tree cleaner and more maintainable. The choice depends on the complexity and scale of your application. 

Differences between Redux and useContext 

React Native Redux vs. useContext: Main Differences 

  1. State Management Style: 
  • Redux: Centralized, single global store. All state is held in one place, and components can access and update it via actions and reducers
  • useContext: Decentralized, uses React’s Context API. State is shared between components without requiring a global store, but state is typically scoped to a subtree of components. 
  1. Scalability: 
  • Redux: Suitable for larger applications with complex state logic because it offers predictable state management patterns. More structure and tooling (like middlewares) for handling side effects. 
  • useContext: Better for smaller apps or for managing simpler, localized state. It can become challenging to maintain and scale with complex applications due to lack of middleware or action-based state flow. 
  1. Boilerplate: 
  • Redux: More boilerplate code (setting up store, reducers, actions). This is often necessary for the stricter pattern but can be cumbersome. 
  • useContext: Less boilerplate; integrates seamlessly into React with hooks. It’s lighter but doesn’t have the strict structure that Redux imposes. 
  1. Side Effects Handling: 
  • Redux: Provides support for handling side effects via middleware like redux-thunk or redux-saga
  • useContext: No native way to handle side effects. You would need to use other hooks like useReducer or useEffect to manage side effects, which can become complicated as the app grows. 
  1. Debugging Tools: 
  • Redux: Redux DevTools provide advanced debugging and state tracking capabilities, making it easier to trace state changes. 
  • useContext: No built-in debugging tools like Redux. State changes are harder to track, especially in larger apps. 
  1. Performance: 
  • Redux: Uses selectors to optimize performance by preventing unnecessary re-renders when only specific parts of the state are updated. 
  • useContext: Any context update will cause all consuming components to re-render, which can lead to performance issues in larger apps. 

Installation and Usage 

1. Redux (React-Redux) in React Native 

Installation:   npm install @reduxjs/toolkit react-redux 

2. Basic SetupCreate the store 

3. Provide the store: Wrap your app with the <Provider> component to give access to the store. 

4. Using Redux in a component

a. Access state: Use useSelector to access the store’s state. 

b. Dispatch actions: Use useDispatch to dispatch actions. 



useContext with React Native 

  1. Installation: No external package needed. 
     
  1. Basic Setup


    a. Create a context: 


b. Using context in a component

Access context: Use useContext to access the context value. 

c. Provide the context: Wrap the component tree that needs access to the context inside the provider. 



When to Use Redux vs. useContext? 

  1. Use Redux when: 

a. Your app has a large state that needs to be shared across many unrelated components. 

b. You need predictable and maintainable state management with debugging and middleware support. 

c. Your state logic involves complex transformations or side effects (i.e., asynchronous operations). 

  1. Use useContext when: 

a. Your app is small or medium-sized, and you need to share a small amount of state between a few components. 

b. You want a simple, quick solution without introducing much boilerplate. 

c. Your state is localized to certain component trees and doesn’t require complex state logic or side effects. 

Categories
Technology

Automate and deploy Android and iOS Builds using Fastlane and Self-Hosted Runners

Automate and deploy Android and iOS Builds using Fastlane and Self-Hosted Runners

Introduction :

Why automate Android and iOS builds?

Automating Android and iOS builds focuses on the build and deployment steps in the Software Development Life Cycle (SDLC) to save time. By automating these processes, we reduce manual intervention, minimize errors, and ensure faster and more consistent delivery of application updates.

Continuous Integration and Continuous Deployment (CI/CD) pipelines are crucial in modern mobile app development. They ensure that code changes are automatically built, tested, and deployed, reducing manual effort and the risk of errors.

Introduction to CI/CD Pipeline

Continuous Integration (CI) and Continuous Delivery (CD) are practices that enable development teams to deliver code changes more frequently and reliably.

Continuous Integration (CI): Developers merge their code changes into a central repository. Automated builds and tests are run to ensure that the new code does not introduce any bugs or break existing functionality.

Continuous Delivery (CD): Once code passes CI, it is automatically deployed to a staging environment. From there, it can be released to production with a manual approval step.

Tools: Jenkins, GitHub Actions, GitLab CI, CircleCI, Travis CI.

Benefits of a CI/CD Pipeline

  • Faster Development Cycles: Automated processes reduce the time required for code integration and deployment.
  • Improved Code Quality: Continuous testing ensures that code changes do not introduce new bugs or regressions.
  • Enhanced Collaboration: Teams can collaborate more effectively with a streamlined workflow.
  • Reduced Manual Effort: Automation minimizes manual intervention, reducing human error and freeing up developer time for more critical tasks.

The primary goal is to ensure that code changes are integrated and delivered to production rapidly and safely.

Introduction to Self-Hosted Runners

Self-hosted runners are machines that you manage and maintain to run GitHub Actions workflows. Unlike GitHub-hosted runners, which are managed by GitHub, self-hosted runners provide more control over the hardware, operating system, and software environment.

Step-by-Step Guide

  • Create a Runner:     
    a. Go to your repository on GitHub.
    b. Navigate to Settings > Actions > Runners > New self-hosted runner.
    c. Choose the operating system for your runner (Linux, macOS, or Windows).
  •  Download and Configure the Runner: Follow the provided steps to setup self-       hosted runners.

Introduction to Fastlane

  • Fastlane is an open-source platform designed to streamline the process of building, testing, and releasing mobile applications for iOS and Android. It automates many repetitive tasks in the app development lifecycle, making it easier and faster for developers to deploy their apps.

Setting Up Fastlane for Android and iOS

  • Installing Fastlane :  
                              Fastlane can be installed in multiple ways. The preferred method is with Bundler. Fastlane can also be installed directly through Homebrew (if on macOS). It is possible to use macOS’s system Ruby, but it’s not recommended, as it can be hard to manage dependencies and cause conflicts.
  • Setting up Fastlane :   
         Navigate your terminal to your project and run ‘Fastlane init’ inside android and iOS directory.

        This will create Fastlane folder inside our project android and iOS directory.

Deploy Android and iOS Builds to Firebase

Android fastlane code

iOS fastlane code

Integrating Fastlane with GitHub Actions

Integrating Fastlane with CI/CD (Github Actions) pipelines is essential for automating the build, test, and deployment processes for mobile applications. This integration ensures that each code change is automatically built, tested, and deployed, improving efficiency and reducing the risk of human errors.

Explanation:

  • Trigger: The pipeline runs on push events to the main branch and on pull requests
    Or on Workflow_dispatch on manual trigger.
  • Jobs:
    a. Build: Checks out the code, sets up the JDK, caches Gradle dependencies, builds the app, runs unit tests, and uploads the APK.
    b. Deploy: Deploys the apk or aab to Firebase App Distribution/Playstore/Appstore (after the build job succeeds).

 Workflow in Github Actions

Common Issues and Troubleshooting

Categories
Technology

Android Letter Boxing

Android letterboxing refers to the technique used to maintain aspect ratio compatibility when running apps on devices with different screen sizes and aspect ratios. It ensures that the app’s content remains within a specified safe area, preventing stretching or distortion on non-standard screens.

Purpose: To enhance user experience by allowing apps to adapt gracefully to various device configurations, especially on larger screens where the aspect ratios differ significantly from traditional smartphones.

Features of Android Letterboxing

  • Aspect Ratio Preservation:

Android letterboxing preserves the original aspect ratio of the app’s content, preventing visual distortions or stretching on devices with different aspect ratios.

  •   Safe Area Definition:                                                     
    It defines a safe area within which the app’s essential content is displayed, ensuring that crucial UI elements remain visible and usable on all screen sizes.
  • Uniform User Experience:
    Ensures a consistent user experience across various Android devices by adapting the app’s layout and content presentation dynamically.
  • Compatibility:
    Supports different screen sizes and resolutions, maintaining compatibility with a wide range of Android devices, including tablets and foldable phones.

Implementing Android Letterboxing

Design Considerations

  • Define Safe Areas: Identify and define the critical UI elements and content that must remain visible and accessible across different screen sizes.
  • Aspect Ratio Handling: Design UI layouts and resources to adapt flexibly to varying aspect ratios while maintaining visual integrity.
  • Code snippet :

{ height, width } = Dimensions.get(‘window’)

 aspectRatio = height / width

 Mindimension = Math.min(height, width)

(mindimension >= 600) || (aspectRatio < 1.6)

Implementation Steps

  • Use Constraint Layout: Utilize Constraint Layout with guidelines and constraints to define flexible UI layouts that adjust to different screen sizes.
  • Dynamic Dimension Handling: Implement dynamic dimension calculations and adaptive layout strategies to adjust UI elements based on the available screen space.
  • Resource Qualifiers: Use resource qualifiers (res/layout-wXXXdp) to provide different layout configurations optimized for specific screen widths or aspect ratios.
  • Code snippet :

Boolean isTabletAndroid = getResources().getBoolean(R.bool.isTabletAndroid)

Testing and Validation

  • Device Emulators: Test the app on various Android emulators to simulate different screen sizes and aspect ratios.
  • Real Device Testing: Conduct thorough testing on real devices, including devices with non-standard aspect ratios (e.g., foldable phones), to validate the effectiveness of the letterboxing implementation.

Best Practices

  • Consistency: Maintain a consistent UI design across different devices by adhering to Material Design guidelines and platform-specific UI standards.
  • Performance Optimization: Optimize app performance by minimizing unnecessary UI redraws and ensuring efficient layout rendering on all supported devices.
  • Accessibility: Ensure accessibility considerations are integrated into the letterboxing design, making UI elements accessible and usable for all users.

Conclusion

In conclusion, Android letterboxing is a crucial technique for ensuring app compatibility and maintaining visual integrity across diverse Android devices. By implementing letterboxing effectively and following best practices, developers can deliver a seamless user experience regardless of device screen size or aspect ratio.

References