Blog

iOS – 3 Best Quick Ways To Handle Multithreading In iOS

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about three best available options to handle multithreading in iOS. Production applications will often need to perform heavier operations such as downloading high-resolution images or a executing non-cached database queries. To prevent stalling the main thread (and a hit in frame rate), Apple has provided a few tools to help us. We will discuss below available options to handle multithreading:

  • Grand Central Dispatch
  • NSOperation and NSOperationQueue
  • performSelectorInBackground

A famous quote about Learning is :

” I am always ready to learn although I do not always like being taught. “


So Let’s begin.


1. Grand Central Dispatch

Grand Central Dispatch is a technology that abstracts away the low-level details of multithreading. When using GCD, we only have to think about the tasks we want to perform. These tasks can then be added to serial or concurrent queues. Moreover, we can add tasks to groups and run code after all tasks within the group complete.

Let’s walk through an example where we download an image from a remote URL and then use it to populate a UIImageView.

// Assume we have an `imageView` property on self
private func loadWallpaper() {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { [weak self] in
        guard
            let wallpaperURL = NSURL(string: "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-157301.jpg"),
            let imageData = NSData(contentsOfURL: wallpaperURL)
        else {
            return
        }

        dispatch_async(dispatch_get_main_queue()) {
            self?.imageView.image = UIImage(data: imageData)
        }
    }
}

Most uses of GCD start with a call to dispatch_async, which takes in a queue to use and the block to execute. In our example, we’d like to execute the wallpaper download on a background queue, so we make use of the system-defined global queue with a background quality of service (QoS), DISPATCH_QUEUE_PRIORITY_BACKGROUND. The flag passed into dispatch_get_global_queue should always be 0.

Now we have the block of work to execute. We construct a NSURL via its fail-able String initializer and then fetch the data associated with that resource via NSData(contentsOfURL:). If the above step completes successfully (else we just return from the block), we now have our data at hand.

To update imageView‘s image property, we need to make sure we return to the main thread via dispatch_async(dispatch_get_main_queue()) { /* ... */ }Remember in iOS, all UI updates should be performed on the main thread. Inside the main thread block, we set the image using the NSData initializer on UIImage.

Now that we’ve seen a one-off block example, let’s dive into how we can accomplish groups of dependent tasks. Imagine we wanted to download multiple wallpapers and present an alert to the user when all of the images finish loading. Dispatch groups will be our best friends in these scenarios.

First, let’s refactor the loadWallpaper function from the previous example to accept a dispatch_group_t and a target URL.

private func loadWallpaper(group: dispatch_group_t, url: String) {
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { [weak self] in
        defer {
            dispatch_group_leave(group)
        }

        guard
            let wallpaperURL = NSURL(string: url),
            let imageData = NSData(contentsOfURL: wallpaperURL)
        else {
            // In production scenarios, we would want error handing here
            return
        }

        // Use imageData in some manner, e.g. persisting to a cache, present in view hierarchy, etc.
        print("Image downloaded \(url)")
    }
}

The function has been modified slightly to accept a parameter group of type dispatch_group_t (we’ll go into how to create these groups in the next snippet) and a target URL. Additionally, our previous call to dispatch_async has been replaced with dispatch_group_async, signalling that the block should be associated with group. Lastly, after completing our work with the resulting imageData we must notify group that the block is complete via dispatch_group_leave.

To use loadWallpaper(_:url:) a call site could look like so:

private func fetchAllWallpapers() {
        let urls = [
            "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-329991.jpg",
            "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-329805.jpg",
            "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-330201.jpg"
        ]

        let wallpaperGroup = dispatch_group_create()

        urls.forEach {
            dispatch_group_enter(wallpaperGroup)
            loadWallpaper(wallpaperGroup, url: $0)
        }

        dispatch_group_notify(wallpaperGroup, dispatch_get_main_queue()) { [weak self] in
            let alertController = UIAlertController(title: "Done!", message: "All images have downloaded", preferredStyle: .Alert)
            alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))

            self?.presentViewController(alertController, animated: true, completion: nil)
        }
    }

We start by creating a dispatch group, wallpaperGroup, using dispatch_group_create(). With the group in hand, we loop over all of the wallpaper URLs, first signalling to the group that we are about to start an operation by making a call to dispatch_group_enter(wallpaperGroup) (each group entry call must pair with a group leave call). We then proceed to call loadWallpaper(_:url:).

To run code after completion of the group, we specify a block in a dispatch_group_notify call. In our case, we’ll simply present a UIAlertController letting the user know that all of the downloads have finished.

While GCD can be extremely powerful, it can be a bit cumbersome to work with in practice. To help with this, we can use Swifty GCD wrapper .

protocol ExcutableQueue {
    var queue: dispatch_queue_t { get }
}

extension ExcutableQueue {
    func execute(closure: () -> Void) {
        dispatch_async(queue, closure)
    }
}

enum Queue: ExcutableQueue {
    case Main
    case UserInteractive
    case UserInitiated
    case Utility
    case Background

    var queue: dispatch_queue_t {
        switch self {
        case .Main:
            return dispatch_get_main_queue()
        case .UserInteractive:
            return dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)
        case .UserInitiated:
            return dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
        case .Utility:
            return dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)
        case .Background:
            return dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)
        }
    }
}

enum SerialQueue: String, ExcutableQueue {
    case DownLoadImage = "myApp.SerialQueue.DownLoadImage"
    case UpLoadFile = "myApp.SerialQueue.UpLoadFile"

    var queue: dispatch_queue_t {
        return dispatch_queue_create(rawValue, DISPATCH_QUEUE_SERIAL)
    }
}

Using this wrapper, our example above could be rewritten as:

Queue.Background.execute {
    guard
        let url = NSURL(string: "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-157301.jpg"),
        let data = NSData(contentsOfURL: url)
    else {
        return
    }

    Queue.Main.execute { [weak self] in
        self?.imageView.image = UIImage(data: data)
    }
}


2. NSOperation and  NSOperationQueue

NSOperations and NSOperationQueues provide you with a higher-level API, when compared to GCD. They were first introduced in iOS 4 and are actually implemented with GCD under the hood. Typically, we’ll want to use this API over GCD, unless you’re performing a simple unit of work on a specific queue. NSOperations provide us with powerful functionality such as cancellation and dependencies.

To start, we’ll port the wallpaper downloading example to use an NSBlockOperationNSBlockOperation is a simple wrapper on a block of work that can be added to a queue.

private func loadWallpaper(queue: NSOperationQueue, url: String) {
    guard let wallpaperURL = NSURL(string: url) else { return }

    let downloadOperation = NSBlockOperation {
        guard let imageData = NSData(contentsOfURL: wallpaperURL) else { return }

        NSOperationQueue.mainQueue().addOperationWithBlock { [weak self] in
            self?.imageView.image = UIImage(data: imageData)
        }
    }

    queue.addOperation(downloadOperation)
}

The initializer for NSBlockOperation simply takes a block to run. In our case, we’ll download the data from wallpaperURL and return to the main queue to set the image property on imageView. After initializing downloadOperation, we add it to queue.

When creating an NSOperationQueue, we have a few points of customization.

let queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 1

// If you want to hold the queue, use the `suspended` property
queue.suspended = true

The maxConcurrentOperationCount property allows us to set a limit on how many operations may run concurrently in a given queue. Setting this to 1, implies our queue will be serial (queing order may not be preserved, as operations only run when their ready flag is set to true). If this property isn’t set, it defaults to NSOperationQueueDefaultMaxConcurrentOperationCount, which is dictated by system conditions.

By default, all operations that are ready (ready property is true) are run when added to a queue. We can halt all execution on a queue by setting the suspended property to true.

NSOperations become really powerful when we separate them out into operation subclasses. To demonstrate this, let’s make a wallpaper resizing operation. We’ll need to subclass a custom wrapper of NSOperation that has the proper KVO notifications in place.

class ResizeImageOperation: Operation {

    enum Error {
        case FileReadError
        case ResizeError
        case WriteError
    }

    let targetSize: CGSize
    let path: NSURL
    var error: Error?

    init(size: CGSize, path: NSURL) {
        self.targetSize = size
        self.path = path
    }

    override func execute() {
        // Need to signal KVO notifications for operation completion
        defer {
            finish()
        }

        guard let sourceImage = UIImage(contentsOfFile: path.absoluteString) else {
            error = Error.FileReadError
            return
        }

        let finalWidth: CGFloat, finalHeight: CGFloat
        let ratio = sourceImage.size.width / sourceImage.size.height

        // Scale aspect fit the image
        if sourceImage.size.width >= sourceImage.size.height {
            finalWidth = targetSize.width
            finalHeight = finalWidth / ratio
        } else {
            finalHeight = targetSize.height
            finalWidth = finalHeight * ratio
        }

        let imageSize = CGSize(width: finalWidth, height: finalHeight)
        UIGraphicsBeginImageContextWithOptions(imageSize, true, 0.0)
        defer { UIGraphicsEndImageContext() }

        let rect = CGRect(origin: .zero, size: imageSize)
        sourceImage.drawInRect(rect)

        guard
            let resizedImage = UIGraphicsGetImageFromCurrentImageContext(),
            let imageData = UIImageJPEGRepresentation(resizedImage, 1.0)
        else {
            error = Error.ResizeError
            return
        }

        guard imageData.writeToFile(path.absoluteString, atomically: true) else {
            error = Error.WriteError
            return
        }
    }
}
  • To help with error handling, we add a nested Error enum with a few cases.
  • ResizeImageOperation can be initialized with a target size and path to write,
  • The meat of the operation is placed in the execute method (overridden from Operation). We need to make sure to defer a call to finish(), so that the Operation superclass can signal the proper KVO notifications.
  • We then proceed with the resizing the image (scale aspect fit) and saving it to disk.

Now that we have a resizing operation in hand, let’s refactor our download operation a bit to work with it:

private func downloadWallpaper(url: NSURL, path: NSURL) -> NSOperation {
    return NSBlockOperation {
        guard
            let imageData = NSData(contentsOfURL: url),
            let image = UIImage(data: imageData)
        else { return }

        UIImageJPEGRepresentation(image, 1.0)?.writeToFile(path.absoluteString, atomically: true)
    }
}

We now return an NSOperation and have the operation write the image data to disk. Lastly, to make the download and resize operations dependent, we can use them like so:

// Assume self has `imageView` and `wallpaperQueue` properties

if
    let cacheDirectory = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true).first,
    let cacheDirectoryURL = NSURL(string: cacheDirectory)
{

    let targetURL = cacheDirectoryURL.URLByAppendingPathComponent("wallpaper.jpg")
    let downloadOperation = downloadWallpaper(NSURL(string: "http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-329991.jpg")!, path: targetURL)

    let resizeOperation = ResizeImageOperation(size: CGSize(width: imageView.bounds.size.width * 2, height: imageView.bounds.size.height * 2), path: targetURL)
    resizeOperation.addDependency(downloadOperation)

    resizeOperation.completionBlock = { [weak self, weak resizeOperation] in
        if let error = resizeOperation?.error {
            print(error)
            return
        }

        guard
            let path = resizeOperation?.path,
            let imageData = NSData(contentsOfFile: path.absoluteString)
        else {
            return
        }

        NSOperationQueue.mainQueue().addOperationWithBlock {
            self?.imageView.image = UIImage(data: imageData)
        }
    }

    wallpaperQueue.suspended = true
    wallpaperQueue.addOperation(downloadOperation)
    wallpaperQueue.addOperation(resizeOperation)
    wallpaperQueue.suspended = false
}
  • The key line to notice is resizeOperation.addDependency(downloadOperation). That’s how we express the resizing operation’s dependency on downloadOperation.
  • Moreover, in the completion block of resizeOperation, we check for errors and proceed with displaying the resized image.
  • Note: we make sure to suspend the queue first, then add the operations. This prevents the operations from beginning immediately upon addition.


3. PerformSelectorInBackground

To wrap up, let’s show a simple example of performSelectorInBackground. Assuming self has a method sleepAndPrint(_:), we can make the following call:

performSelectorInBackground("sleepAndPrint:", withObject: "supsup")

If our target selector had no argument, the selector would simply be "sleepAndPrint").

func sleepAndPrint(message: String) {
    NSThread.sleepForTimeInterval(1)
    print(message)
}

That’s all about in this article.


Conclusion

In this article, We understood about three best available options to handle multithreading in iOS. We’ve discussed about GCD, NSoperations, and NSObject‘s performSelectorInBackground method as means of performing work in a multithreaded fashion. If we have small units of work to perform, we’ll want to reach for GCD or performSelectorInBackground. On the other hand, if we have larger operations that may have dependencies, NSOperation should be our tool of choice.

Thanks for reading ! I hope you enjoyed and learned about three best available options to handle multithreading in iOS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

Android – Understanding Property Delegation In Kotlin

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about Property Delegation concepts in Kotlin. The Kotlin programming language has native support for class properties. Properties are usually backed directly by corresponding fields, but it does not always need to be like this – as long as they are correctly exposed to the outside world, they still can be considered properties. This can be achieved by handling this in getters and setters, or by leveraging the power of Delegates.

We will discuss the below topics to understand the Property Delegation Concepts in Kotlin:

  • What is Property Delegation?
  • What are Default Delegated Properties in Kotlin?
  • How to create a custom Delegation Property?
  • How to use Kotlin Delegation Property with Android Development?

A famous quote about Learning is :

” The beautiful thing about learning is that nobody can take it away from you.”


So Let’s begin.


What is Property Delegation?

A “Delegate” is just a class that provides the value of a property and handles its changes. This will help us to delegate(assign or pass on)the getter-setter logic altogether to a different class so that it can help us in reusing the code.

Simply put, delegated properties are not backed by a class field and delegate getting and setting to another piece of code. This allows for delegated functionality to be abstracted out and shared between multiple similar properties – e.g. storing property values in a map instead of separate fields.

Delegated properties are used by declaring the property and the delegate that it uses. The by keyword indicates that the property is controlled by the provided delegate instead of its own field.

This is an alternative to inheritance property.


What are Default Delegated Properties in Kotlin?

Kotlin contains some inbuilt examples for Delegated Properties such as:

  • lazy properties: the value gets computed only upon first access;
  • observable properties: listeners get notified about changes to this property;
  • storing properties in a map, instead of a separate field for each property.


How to create a custom Delegation Property?

For the case of simplicity, let’s take a very simple use-case. Let’s consider a scenario where we want a String property that always gets trimmed and has a common appended string after the original value.

The general way we would do this is:

var string: String = ""
    set(value) {
        field = "${value.trim()} is a String!"
    }
fun main() {
    string = "checking.....        "
    println(string)
}

//output: checking..... is a String!

We can see that the extra spaces are trimmed and the required string is appended.

Well, this is good for one variable. What if we have a bunch of string variables containing the same functionality?

We have to keep adding this setter property repeatedly:

var stringOne: String = ""
    set(value) {
        field = "${value.trim()} is a String!"
    }
var stringTwo: String = ""
    set(value) {
        field = "${value.trim()} is a String!"
    }
var stringThree: String = ""
    set(value) {
        field = "${value.trim()} is a String!"
    }
.
.
.
.

This meets our requirement but we see a lot of repetitive code. So, how can we resolve this?

Yes, We can resolve by Property Delegation!

Here, we shall “delegate” the property of trimming and appending the common string to a separate class so that we can reuse this wherever required.

There will be times that we want to write our delegates, rather than using ones that already exist. This relies on writing a class that extends one of two interfaces – ReadOnlyProperty or ReadWriteProperty.

Both of these interfaces define a method called getValue – which is used to supply the current value of the delegated property when it is read. This takes two arguments and returns the value of the property:

  • thisRef – a reference to the class that the property is in
  • property – a reflection description of the property being delegated

The ReadWriteProperty interface additionally defines a method called setValue that is used to update the current value of the property when it is written. This takes three arguments and has no return value:

  • thisRef – A reference to the class that the property is in
  • property – A reflection description of the property being delegated
  • value – The new value of the property

Let’s understand by String Trimming Example below as step by step .

  • Let’s create a custom class, let’s name it TrimAppendDelegate
  • To use this class as a Delegate, we have to implement the ReadWriteProperty<> interface
  • Once we implement the interface, we have to implement the abstract members in the interface which are getValue and setValue
  • Finally, we define a private variable of String type(since we are defining a custom Delegate for our String property) inside our Delegate class and define the getValue and setValue properties.
class TrimAppendDelegate : ReadWriteProperty<Any, String> {
    private var trimAppendedString = ""
    override fun getValue(thisRef: Any, property: KProperty<*>) =   trimAppendedString

override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {
        trimAppendedString = "${value.trim()} is a String!"
    }
}
}

//Usage :

private var trimmedString by TrimAppendDelegate()
trimmedString = "This..      "
println(trimmedString)

//Output : This.. is a String!

This is how we can achieve the property of Delegation.


How to use Kotlin Delegation Property with Android Development?


Using Built-in delegated property Lazy:

Most of the time, we see the usage of lateinit var in our UI(Activities/Fragments) classes or View Models. We can use the concept of the lazy delegate in place of lateinit var. The variable will be initialized the first time it is used.


Using Built-in delegated property Observable:

  • Most of our Android applications use Recycler views. We know that every recycler view is associated with its respective adapter. Every time the data structure (list of objects) changes in the adapter, we call notifyDataSetChanged to update our Recycler view.
  • We can use the inbuilt delegated property “Observable” to get the old and changed values of the data structure(list of objects)
private var users: ArrayList<User> by Delegates.observable(arrayListOf()) { property, oldValue, newValue ->
    Log.d("Old value ${property.name} size", "${oldValue.size}")
    Log.d("New value ${property.name} size", "${newValue.size}")
    notifyDataSetChanged()
}

In the above code snippet, we can consider User as one of the model classes, and “users” is a list of User objects. We can access the old and new values whenever the value for “user” changes. Finally, we can call notifyDataSetChanged, if there is a change in oldValue and newValue by comparison.

To access the advantage of this Observable delegated property, the parameter should be a “var” instead of “val”. Else the changes cannot be identified, because, val, in Kotlin, is read-only.


Using Built-in delegated property Observable along with Lazy:

We can also use this “Observable” property along with “lazy” for updating our views. This can be very helpful if we are not using the concept of LiveData in our application.

Let’s understand the code snippet :

class MainActivity : AppCompatActivity() {
    
    private val textView: TextView by lazy { textview }
    private var text: String by Delegates.observable("") { _, _, newValue ->
        textView.text = newValue
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        text = "NewText"
    }
    
}

In the above code snippet, We have initiated textView with a lazy delegate just for our safety so that there will be no null pointer exception while accessing it. Whenever there is a change in the “text” variable, the text view is updated with the new value. This is similar to the concept of Live Data.


Using Built-in delegated property Lazy along with Custom Delegate:

Let’s say we want to save a boolean shared preference in our MainActivity.kt file (Any activity class file). Let’s create a custom delegate to store a Boolean shared preference value:

//Delegating the boolean preference saving option
class BooleanPreference(
    private val preferences: Lazy<SharedPreferences>,
    private val name: String,
    private val defaultValue: Boolean
) : ReadWriteProperty<Any, Boolean> {
    
    @WorkerThread
    override fun getValue(thisRef: Any, property: KProperty<*>): Boolean {
        return preferences.value.getBoolean(name, defaultValue)
    }
    override fun setValue(thisRef: Any, property: KProperty<*>, value: Boolean) {
        preferences.value.edit().putBoolean(name, value).apply()
    }
    
}

We can see that our custom delegate class takes three parameters, the preferences instance, the name(Key in this case), and the default value.

So, let’s create our shared preferences global instance in our Activity file.

private val prefs: Lazy<SharedPreferences> = lazy { // Lazy to prevent IO access to main thread.
    this.applicationContext.getSharedPreferences(
        PREFS_NAME, MODE_PRIVATE
    )
}
companion object {
    const val PREFS_NAME = "Preferences"
    const val TOGGLE_PREFS = "toggle"
}

Let’s say we are handling the preference of a toggle here in our Activity class. We can just use our custom delegate as follows:

private var togglePreference by BooleanPreference(prefs, TOGGLE_PREFS, false)

Now, let’s say if we want to change the value in the onCreate method(or any click listener, in general):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    togglePreference = true
    Toast.makeText(this, "$togglePreference", Toast.LENGTH_SHORT).show()  // Shows true
}

We just use it as a simple variable assignment. Looks clean and concise!

That’s all about in this article.


Conclusion

In this article, We understood about Property Delegation concepts in Kotlin. We have discussed about What is Property Delegation, Default Delegated Properties, create Custom Property Delegation and how to use Property delegation with Android Development. Property delegation is a powerful technique, that allows you to write code that takes over control of other properties, and helps this logic to be easily shared amongst different classes. This allows for robust, reusable logic that looks and feels like regular property access.

Thanks for reading ! I hope you enjoyed and learned about Property Delegation concepts in Kotlin. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – How To Make Our iOS Applications More Secure ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about iOS App Security. Mobile applications are the center of most peoples’ technology usage. They deal with a lot of private and sensitive user data like your personal health information or banking information. Protecting this data as well as possible is heavily important and the topic of this article.

We’ll discuss concrete techniques for making our iOS apps more secure. Our best practices cover means for securely storing data as well as sending & receiving data over the network. We’ll see why it is so hard to get security right and how we can improve our app security by using services from Apple and other providers.

We will focus on three main topics related to iOS App Security:

  • Storing user data safely.
  • Secure data transportation.
  • How to use Apple’s new cryptographic APIs.

A famous quote about Security and Learning is :

” Learning how to live with insecurity is the only security. “


So Let’s begin.

Chances are that our app handles private data that we don’t want to end up in the wrong hands. Therefore, we need to make sure to store this data safely and make data transportation as secure as possible.


Best Practices for Storing User Data

If we are developing iOS apps lots of security features are already provided by the OS. All iOS devices with an A7 processor or later also have a coprocessor called the Secure Enclave. It powers iOS security features in a hardware-accelerated way.


Apple’s App Sandbox

All apps running on iOS run in a sandbox to make sure the app can only access data which is stored in the app’s unique home directory. If an app wants to access data outside of its home directory it needs to use services provided by iOS, like the ones available for accessing iCloud data or the photo album. Therefore, no other app can read or modify data from our app.

Apple’s App Sandbox is powered by UNIX’s user permissions and makes sure that apps get executed with a less privileged “mobile” user. Everything outside the app’s home directory is mounted read-only. All system files and resources are protected. The available APIs don’t allow apps to escalate privileges in order to modify other apps or iOS itself.

For performing specific privileged operations an app needs to declare special entitlements. These entitlements get signed together with the app and are not changeable. Examples of services that need special entitlements are HealthKit or audio input. Some entitlements are even restricted to be only used if Apple gives you access to them. This includes services like CarPlay. They are stronger protected because misusing them could have fatal consequences.

Next to entitlements giving us special rights, apps can make use of the iOS extensions system. The OS has many points to be used by app extensions. App extensions are single-purpose executables bundled with the app. They run in their own address space and get controlled by the OS.

Additionally, iOS has methods to prevent memory-related security bugs. Address space layout randomization (ASLR) randomizes the assigned memory regions for each app on every startup. This makes the exploitation of memory-corruption-bugs much less likely. Also, memory pages are marked as non-executable with ARM’s Execute Never (XN) feature to stop malicious code from being executed.


Data Protection API

All iOS versions since iOS 4 have a built-in security feature called Data Protection. It allows an app to encrypt and decrypt the files stored in their app directory. The encryption and decryption processes are automatic and hardware-accelerated. Data Protection is available for file and database APIs, including NSFileManager, CoreData, NSData, and SQLite.

The feature is enabled by default but can be configured on a per-file basis to increase security. Every file can be configured to use one of 4 available protection levels. By default, all files are encrypted until the first user authentication but it might make sense to increase the protection level for certain data.

The four available protection levels include:

  • No protection: The file is always accessible and not encrypted at all
  • Complete until first user authentication: This is enabled by default and decrypts the file after the user unlocks their device for the first time. Afterward, the file stays decrypted until the device gets rebooted. Locking the device doesn’t encrypt the data again.
  • Complete unless open: The file is encrypted until the app opens the file for the first time. The decryption stays alive even when the device gets locked by the user.
  • Complete: The file is only accessible when the device is unlocked.

We can specify the protection level when we create files like this:

try data.write(to: fileURL, options: .completeFileProtection)

But we are also able to change the protection level of existing files by setting the resource values:

try (fileURL as NSURL).setResourceValue( 
                  URLFileProtection.complete,
                  forKey: .fileProtectionKey)

It is important to understand which protection levels fits our needs. By default, we should use the highest protection level possible. However, if we need access to files in the background while the phone is locked we can’t use complete data encryption for them.


Keychain

The keychain is our secure place to store small chunks of data. It is a hardware-accelerated secure data storage that encrypts all of its contents. It is used by the system to store data like passwords and certificates but we as an app developer have also access to this data storage.

Our app or app group has its own space in the keychain and no other app has access to it. This way, we don’t need to store encryption keys in our app and can rely on the system to provide the highest level of security.

The keychain is the secure key-value storage replacement for NSUserDefaults. NSUserDefaults are not encrypted at all and should be avoided for sensitive data.

For every keychain item, we can define specific access policies for accessibility and authentication. We can require user presence (requesting Face ID or Touch ID unlock) or that the biometric ID enrolment didn’t change since the item was added to the keychain.

As an additional feature of the iOS Keychain, we can decide if we want to store the information in the local keychain which is only available on this specific device, or in the iCloud Keychain which gets synchronized across all Apple devices. This gives us the ability to share the information between our iPhone, iPad and Mac counterparts.

Even though the Keychain Services API should be used whenever possible, its interface is not exactly nice to use in Swift. If we plan to use such functionality more often in our codebase consider wrapping it with a nicer Swift API.

let query: [String: Any] = [
    kSecClass as String: kSecClassInternetPassword,
    kSecAttrAccount as String: account,
    kSecAttrServer as String: server,
    kSecValueData as String: password
]

let status = SecItemAdd(query as CFDictionary, nil)

This code snippet stores some credentials to the keychain. A lot of casting is necessary and in the end, we call SecItemAdd which synchronously stores the credentials and returns either a success or error status code.


Best Practices for Secure Data Transportation

Next to storing the user data safely, we should make sure that the communication between our app and its remote counterparts is secured. This prevents attackers from collecting private data by sniffing the network traffic or by running malicious servers.


HTTPs

Most network communication is done over the HTTP protocol between a client and a server. By default, HTTP connections are not encrypted. It is easily possible for attackers to sniff data from our local network or to perform man-in-the-middle attacks.

Since iOS 9, there is a new feature called App Transport Security (ATS). It improves the security of network communication in our apps. ATS blocks insecure connections by default. It requires all HTTP connections to be performed using HTTPS secured with TLS.

ATS can be configured in many ways to loosen up these restrictions. We can, therefore, allow insecure HTTP connections for specific domains or change the minimum TLS version used for HTTPS.

If our app contains an in-app browser we should use the NSAllowsArbitraryLoadsInWebContent configuration which allows our users to browse the web normally and still makes sure that all other network connections in our app use the highest security standards.


SSL Pinning

By default, HTTPS connections are verified by the system: it inspects the server certificate and checks if it’s valid for this domain. This should make sure the connected server is not malicious. However, there are still ways for attackers to perform more complex man-in-middle attacks.

The system certificate trust validation checks if the certificate was signed by a root certificate of a trusted certificate authority. To circumvent this security mechanism attackers would need to explicitly trust another malicious certificate in the user’s device settings or compromise a certificate authority. The attacker could then perform a man-in-the-middle attack to read all messages sent between client and server.

To prevent these kinds of attacks an app can perform additional trust validation of server certificates. This is called SSL or Certificate Pinning. We can implement SSL Pinning by including a list of valid certificates (or its public keys or its hashes) in our app bundle. The app can, therefore, check if the certificate used by the server is on this list and only then communicate with the server.

Implementing this validation from scratch should be avoided since implementation mistakes are very likely and lead to even more security vulnerabilities. We can recommend using an Open Source framework like TrustKit.

Introducing SSL Pinning, unfortunately, introduces the risk of bricking our app. Since we hardcode the trusted certificates, the app itself needs to be updated if a server certificate expires. To avoid such a situation, pin the future certificates in the client app before releasing new server certificates.


Push Notifications

To send push notifications to our users, we need to use Apple’s APNS services. If we want to use end-to-end encryption or if we just don’t want to give Apple the (theoretical) chance to read your messages you can use UNNotificationServiceExtension extensions to modify the messages on the client-side.

This allows us to send either encrypted messages to our clients or use placeholders for sensitive data. The messages will simply be used as a wakeup call for the app. The app can then decrypt the message or respectively for placeholder messages fetch the necessary information from the local device and replace the placeholders with the sensitive data. The clear text message will then be shown on the user’s lock screen without any sensitive information being sent to Apple’s servers.

In the following example, we can see how easily we can change our message content in our notification service extension.

class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        guard let mutableContent = request.content.mutableCopy() as? UNMutableNotificationContent else {
            fatalError("Cannot convert notification content to mutable content")
        }

        mutableContent.title = decryptText(mutableContent.title)
        mutableContent.body = decryptText(mutableContent.body)

        contentHandler(mutableContent)
    }

    // ...

}


End-to-end encryption

End-to-end encryption is the “holy grail” for secure data transportation. It allows us to encrypt messages in a way that only the sender and receiver can decrypt them and neither Apple or our servers can read the cleartext data.

End-to-end encryption is not easy to implement and requires a lot of experience in cryptographic processes. If our team doesn’t have the experience it is very advisable to consult a third party expert helping with the implementation of the encryption mechanism.


CloudKit

If our app doesn’t need a server , we can use Apple’s CloudKit. CloudKit allows us to store data in iCloud containers while using our Apple ID as the login mechanism for our app. This way, we don’t need to implement all of these services on our own.

CloudKit was made with security in mind. As an app developer, we don’t have access to concrete user data and the communication is encrypted by default.

All the communication between our app and the server can be done using Apple’s client-side CloudKit framework. If we have an additional Android or Web app, we can still use CloudKit using its JavaScript and Web services.

To make this even better: CloudKit is completely free of charge to a certain amount. We can reach millions of users without fearing costs for traffic, data storage or requests.


Best Practices of Using Apple’s cryptographic APIs

The iOS SDK includes APIs to handle common cryptographic tasks for us. As we said above it is generally a good idea to rely on proven crypto implementations and not reimplement them ourself.


Apples CryptoKit

Apples CryptoKit is a new API that was introduced in iOS 13 and provides lower-level APIs to perform cryptographic operations or implement security protocols.

CryptoKit is based on top of more lower-level APIs. They were available before but introduced additional risk factors since developers often used them in a wrong way.

CryptoKit also allows us to use the SecureEnclave to get cryptographically safe functions that are performant and optimized for the device’s hardware.

If we want to support older iOS versions, we can use those lower-level APIs or use well known open-source third-party libraries like CryptoSwift.


Hashing data

Hash functions are functions that convert data of arbitrary size to fixed-size values. Good hash functions should minimize duplication of output values (so-called collisions) and be very fast to compute. Swift includes hashing functionality in the Swift Standard Library, but these functions are heavily focused on being fast and have a relative high collision rate. This makes them a good fit for performance-critical operations, but not so much for security related operations.

Securely hashing data is simple using CryptoKit. We just need to call the hash function on one of our Structs and choose a hash algorithm. CryptoKit supports the most common ones from SHA512 to SHA256.

let data = ...
let dataDigest = SHA512.hash(data: data)
let hashString = dataDigest.description


Authenticating Data using Message authentication codes

A message authentication code (MAC) is used to authenticate the sender of a message and confirm the integrity of that message. It allows the receiver to verify the origins of messages and detect changes to the message’s content.

To use this kind of integrity checks we can, for example, use CryptoSwift’s hashed authentication codes, also known as HMACs. The HMAC struct is a generic type that can be used with all the hash functions included in CryptoSwift.

To create a message authentication code , we can use this simple code snippet.

let key = SymmetricKey(size: .bits256)

let authenticationCode = HMAC<SHA256>.authenticationCode(for: messageData, using: key)

We can verify the message by using:

let isValid = HMAC<SHA256>.isValidAuthenticationCode(
    Data(authenticationCode),
    authenticating: messageData,
    using: key
)

As we can see, we need to create a symmetric key first and securely share it between the sender and receiver.


Encrypting Data using symmetric keys

Encrypting and decrypting data using a symmetric key is simple, too. We can use one of two available ciphers: ChaChaPoly (ChaCha20-Poly1305) or AES-GCM in CryptoSwift:

let encryptedData = try! ChaChaPoly.seal(data, using: key).combined

let sealedBox = try! ChaChaPoly.SealedBox(combined: encryptedData)

let decryptedData = try! ChaChaPoly.open(sealedBox, using: key)

We should always make sure not to hardcode these symmetric keys in our app though. We can generate a symmetric key at runtime and then store it safely in the keychain. That way, no one has access to our key to decrypt data.


Performing Key Agreement

In a lot of cases, we will need to perform some form of key exchange to exchange cryptographic keys over an insecure channel. With key agreement protocols like Elliptic-curve Diffie–Hellman (ECDH), we can derive a common secret.

1. Create private/public key-pairs for Alice and Bob

let alicePrivateKey = P256.KeyAgreement.PrivateKey()
let alicePublicKey = alicePrivateKey.publicKey
let bobPrivateKey = P256.KeyAgreement.PrivateKey()
let bobPublicKey = bobPrivateKey.publicKey

Both Alice and Bob create their own private/public key-pairs and share their public keys.

2. Deriving shared secret

let aliceSharedSecret = try! alicePrivateKey.sharedSecretFromKeyAgreement(with: bobPublicKey)

let bobSharedSecret = try! bobPrivateKey.sharedSecretFromKeyAgreement(with: alicePublicKey)

We were now able to derive a common secret by using the own private key together with the counterpart’s public key. aliceSharedSecret and bobSharedSecret are now the same.

3. The created secret number should not be used as an encryption key by itself. Instead it can be used to generate a much larger and more secure encryption key using HKDF or X9.63 key derivation.

let usedSalt = "Secure iOS App".data(using: .utf8)!

let symmetricKey = aliceSharedSecret.hkdfDerivedSymmetricKey(
    using: SHA256.self,
    salt: protocolSalt,
    sharedInfo: Data(),
    outputByteCount: 32
)

That’s generally how you could implement it! Also note that Apple has an implementation of Diffie-Hellman in iOS as part of Secure Transport.


Creating and Verifying Signatures

If we want to send messages and make sure that the sender is the person we thought it is we can use signatures. To do so, we need a private/public key pair first.

let signingKey = Curve25519.Signing.PrivateKey()
let signingPublicKey = signingKey.publicKey

Using the private key any form of data can be signed.

let data = ...
let signature = try! signingKey.signature(for: data)

This signature is then sent together with the actual data to the receiver which can use the public key to validate the signature.

let isSignatureValid = signingPublicKey.isValidSignature(signature, for: data)

That’s all about in this article.


Conclusion

In this article, We understood about Apple’s iOS security Best Practices. Creating secure and robust iOS applications is not easy. However, we can improve security in our iOS apps without much effort by sticking to best practices. Protecting user data must be a high priority and should never be ignored.

Thanks for reading ! I hope you enjoyed and learned about Apple’s iOS security Best Practices. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

ReactJS – How to Effectively Think In React Hooks ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, we will understand about the rules of React Hooks and how to effectively start using them in our projects. We will discuss the two most important rules of React Hooks and how to effectively think in Hooks.

” React Hooks are a new addition in React 16.8 that let you use state and other React features without writing a class component. In other words, Hooks are functions that let you “hook into” React state and lifecycle features from function components. (They do not work inside class components.)”

A famous quote about learning is :

” The more I live, the more I learn. The more I learn, the more I realize, the less I know. “

So Let’s begin.


What is React Hook?

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class. It mainly uses to handle the state and side effects in react functional component. React Hooks are a way to use stateful functions inside a functional component. Hooks don’t work inside classes — they let you use React without classesReact provides a few built-in Hooks like useState and useEffect. The React hooks do :

  • Best practices
  • Easy to under understand
  • Easy to test
  • Increases the performance and so on.


Why React Hook?

There are two reasons to use React hooks :

  • The first main reason is the Introduce state in a functional component. We know that the states cannot be used in functions. But with hooks, we can use states.
  • Another reason is the handle side effect in react component. It means, now we can use newly introduced state such as useEffect.

But do we should know for some scenarios, there are 3 places where react failsWhile Reuse logic between components :

  • Has Huge components
  • Confusing


Rules Of React Hooks

Hooks are JavaScript functions, but we need to follow two rules when using them :

  1. Call Hooks at the top level;
  2. Only call Hooks from React components.

Let’s look at these rules in more detail :


1. Call Hooks At The Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Always use Hooks at the top level of your React function. By following this rule, we ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

Let’s make a Form component which will have two states:

  • accountName
  • accountDetail

These states will have default values, we’ll make use of the useEffect hook to persist the state to either the local storage of our browser or to the title of our document.

Now, this component will be maybe to successfully manage its state if it remains the same between multiple calls of useState and useEffect.

function Form() {
  // 1. Use the accountName state variable
  const [accountName, setAccountName] = useState('Arun');

  // 2. Use an effect for persisting the form
  useEffect(function persistForm() {
    localStorage.setItem('formData', accountName);
  });

  // 3. Use the accountDetail state variable
  const [accountDetail, setAccountDetail] = useState('Active');

  // 4. Use an effect for updating the title
  useEffect(function updateStatus() {
    document.title = accountName + ' ' + accountDetail;
  });

  // ...
}

If the order of our Hooks changes (which can be possible when they are called in loops or conditionals), React will have a hard time figuring out how to preserve the state of our component.

// ------------
useState('Arun')           // 1. Initialize the accountName state variable with 'Arun'
useEffect(persistForm)     // 2. Add an effect for persisting the form
useState('Active')        // 3. Initialize the accountdetail state variable with 'Active'
useEffect(updateStatus)     // 4. Add an effect for updating the status

// -------------
// Second render
// -------------
useState('Arun')           // 1. Read the accountName state variable (argument is ignored)
useEffect(persistForm)     // 2. Replace the effect for persisting the form
useState('Active')        // 3. Read the accountDetail state variable (argument is ignored)
useEffect(updateStatus)     // 4. Replace the effect for updating the status

// ...

That’s the order React follows to call our hooks. Since the order remains the same, it will be able to preserve the state of our component. But what happens if we put a Hook call inside a condition?

// We're breaking the first rule by using a Hook in a condition
  if (accountName !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', accountName);
    });
  }

The accountName !== '' condition is true on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition false. Now that we skip this Hook during rendering, the order of the Hook calls becomes different:

useState('Arun')           // 1. Read the accountName state variable (argument is ignored)
// useEffect(persistForm)  // This Hook was skipped!
useState('Active')        // 2 (but was 3). Fail to read the accountDetails state variable
useEffect(updateStatus)     // 3 (but was 4). Fail to replace the effect

React wouldn’t know what to return for the second useState Hook call. React expected that the second Hook call in this component corresponds to the persistForm effect, just like during the previous render — but it doesn’t anymore. From that point on, every next Hook call after the one we skipped would also shift by one — leading to bugs.

This is why Hooks must be called on the top level of our components. If we want to run an effect conditionally, we can put that condition inside our Hook.


2. Only Call Hooks From React Components

Don’t call Hooks from regular JavaScript functions. Instead, you can call Hooks from React function components. Let’s take look at the difference between JavaScript function and React component below:

JavaScript Function

import { useState } = "react";

function toCelsius(fahrenheit) {
  const [name, setName] = useState("Arun");
  return (5/9) * (fahrenheit-32);
}
document.getElementById("demo").innerHTML = toCelsius;

Here we import the useState hook from the React package, and then declared our function. But this is invalid as it is not a React component.

React Function


import React, { useState} from "react";
import ReactDOM from "react-dom";

function Account(props) {
  const [name, setName] = useState("Arun");
  return <p>Hello, {name}! The price is <b>{props.total}</b> and the total amount is <b>{props.amount}</b></p>
}
ReactDom.render(
  <Account total={20} amount={5000} />,
  document.getElementById('root')
);

Even though the body of both looks similar, the latter becomes a component when we import React into the file. This is what makes it possible for us to use things like JSX and React hooks inside.

If we happened to import our preferred hook without importing React (which makes it a regular function), we will not be able to make use of the Hook we’ve imported as the Hook is accessible only in React component.


Call Hooks From Custom Hooks

A custom Hook is a JavaScript function whose name starts with use and that may call other Hooks. For example, useUserName is used below a custom Hook that calls the useState and useEffect hooks. It fetches data from an API, loops through the data, and calls setIsPresent() if the specific username it received is present in the API data.

export default function useUserName(userName) {
  const [isPresent, setIsPresent] = useState(false);
  
  useEffect(() => {
    const data = MockedApi.fetchData();
    data.then((res) => {
      res.forEach((e) => {
        if (e.name === userName) {
          setIsPresent(true);
        }
     });
    });
  });
    
  return isPresent;
}

We can then go on to reuse the functionality of this hook in other places where we need such in our application. In such places, except when needed, we don’t have to call useState or useEffect anymore.

By following this rule, we ensure that all stateful logic in a component is clearly visible from its source code.


Function Component Vs Class Component In Hooks

Let’s take a brief look at class components and functional components (with Hooks), before diving into the few Hooks best practices.

The simplest way to define a component in React is to write a JavaScript function that returns a React element:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

The Welcome component accepts props which is an object that contains data and returns a React element. We can then import and render this component in another component.

The class component uses a programming methodology called Encapsulation which basically means that everything relevant to the class component will live within it. Life-cycle methods (constructorscomponentDidMount()render, and so on) give components a predictable structure.

Encapsulation is one of the fundamentals of OOP (Object-Oriented Programming). It refers to the bundling of data within the methods that operate on that data, and is used to hide the values or state of a structured data object inside a class — preventing unauthorized parties’ direct access to them.

With Hooks, the composition of a component changes from being a combination of life-cycle Hooks — to functionalities with some render at the end.


Function Component

The example below shows how custom Hooks can be used in a functional component (without showcasing what the body is). However, what it does or can do is not limited. It could be instantiating state variables, consuming contexts, subscribing the component to various side effects — or all of the above if you’re using a custom hook!

function {
  useHook{...};
  useHook{...};
  useHook{...};
  return (
    ...
  );
}


Class Component

class component requires you to extend from React.Component and create a render function which returns a React element. This requires more code but will also give you some benefits.

class {
  constructor(props) {...}
  componentDidMount() {...}
  componentWillUnmount() {...}
  render() {...}
}

There are some benefits you get by using functional components in React:

  1. It will get easier to separate container and presentational components because you need to think more about your component’s state if you don’t have access to setState() in your component.
  2. Functional components are much easier to read and test because they are plain JavaScript functions without state or lifecycle-hooks.
  3. You end up with less code.
  4. The React team mentioned that there may be a performance boost for functional components in future React versions.

This leads to the first best practice when using React Hooks.


Hooks Best Practices

There are some best practices in writing Hooks the right and effective way as below:

  1. Simplify Your Hooks
  2. Organize And Structure Your Hooks
  3. Use React Hooks Snippets
  4. Put Hooks Rules into Consideration


1. Simplify Your Hooks

Keeping React Hooks simple will give us the power to effectively control and manipulate what goes on in a component throughout its lifetime. Avoid writing custom Hooks as much as possible; we can inline a useState() or useEffect() instead of creating our own hook.

If we find ourself making use of a bunch of custom Hooks that are related in functionality, we can create a custom hook that acts as a wrapper for these. Let’s take a look at two different functional components with hooks below.

Functional Component v1

function {
  useHook(...);
  useHook(...);
  useHook(...);
  return(
    <div>...</div>
  );
}

Functional Component v2

function {
  useCustomHook(...);
    useHook(...);
    useHook(...);
  return(
    <div>...</div>
  );
}

v2 is a better version because it keeps the hook simple and all other useHooks are inline accordingly. This allows us to create functionality that can be reused across different components and also gives us more power to control and manipulate our components effectively. Instead of adopting v1 in which our components are littered with Hooks, we should make use of v2 which will make debugging easy and our code cleaner.


2. Organize And Structure Your Hooks

One of the advantages of React Hooks is the ability to write less code that is easy to read. In some cases, the amount of useEffect() and useState() can still be confusing. When we keep our component organized it will help in readability and keep the flow of our components consistent and predictable. If our custom Hooks are too complicated, we can always break them down to sub-custom Hooks. Extract the logic of our component to custom Hooks to make our code readable.


3. Use React Hooks Snippets

React Hooks Snippets is a Visual Studio Code extension to make React Hooks easier and faster. Currently, five hooks are supported:

  • useState()
  • useEffect()
  • useContext()
  • useCallback()
  • useMemo()

There are two ways (Command and Extension Marketplace) we can add React Hooks snippets to our project:


4. Put Hooks Rules into Consideration

Endeavor to always put the two rules of Hooks we learned earlier into consideration while working with React Hooks.

  • Only call your Hooks at the top level. Don’t call Hooks inside loops, conditions or nested functions.
  • Always call Hooks from React function components or from custom Hooks, don’t call Hooks from regular JavaScript functions.

The ESlint plugin called eslint-plugin-react-hooks enforces these two rules, we can add this plugin to your project if we’d like it as we explain above in rules of hooks section.

Best practices have not been fully resolved because Hooks are still relatively new. So adoption should be taken with precaution one would take in adopting in any early technology. With that in mind, Hooks are the way for the future of React.

That’s all about in this article.


Conclusion

In this article, We understood about the two most important rules of React Hooks and how to effectively think in Hooks. We looked at functional components and some best practices in writing Hooks the right and effective way. As brief as the rules are, it’s important to make them our guiding compass when writing rules. If we are prone to forget it, we can make use of the ESLint plugin to enforce it.

Thanks for reading ! I hope you enjoyed and learned about the Hook Concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING!!???

A Short Note – Understanding React Redux Concepts

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Understanding React Redux Concepts).

In this note series, we will understand about the React Redux concepts in ReactJS.

So Let’s begin.

What were the Major Problems With MVC Framework ?

Following are some of the major problems with MVC framework:

  • DOM manipulation was very expensive
  • Applications were slow and inefficient
  • There was huge memory wastage
  • Because of circular dependencies, a complicated model was created around models and views

What is Flux ?

Flux is an architectural pattern which enforces the uni-directional data flow. It controls derived data and enables communication between multiple components using a central Store which has authority for all data. Any update in data throughout the application must occur here only. Flux provides stability to the application and reduces run-time errors.

What is Redux?

Redux is one of the hottest libraries for front-end development in today’s marketplace. It is a predictable state container for JavaScript applications and is used for the entire applications state management. Applications developed with Redux are easy to test and can run in different environments showing consistent behavior.

What are the three principles that Redux follows?

  1. Single source of truth: The state of the entire application is stored in an object/ state tree within a single store. The single state tree makes it easier to keep track of changes over time and debug or inspect the application.
  2. State is read-only: The only way to change the state is to trigger an action. An action is a plain JS object describing the change. Just like state is the minimal representation of data, the action is the minimal representation of the change to that data. 
  3. Changes are made with pure functions: In order to specify how the state tree is transformed by actions, you need pure functions. Pure functions are those whose return value depends solely on the values of their arguments.

The Main Components of Redux

Redux is composed of the following components:

  1. Action – It’s an object that describes what happened.
  2. Reducer –  It is a place to determine how the state will change.
  3. Store – State/ Object tree of the entire application is saved in the Store.
  4. View – Simply displays the data provided by the Store.

How is Redux different from Flux?

FluxRedux
1. The Store contains state and change logic1. Store and change logic are separate
2. There are multiple stores2. There is only one store
3. All the stores are disconnected and flat3. Single store with hierarchical reducers
4. Has singleton dispatcher4. No concept of dispatcher
5. React components subscribe to the store5. Container components utilize connect
6. State is mutable6. State is immutable
Flux Vs Redux

What are the advantages of Redux?

Advantages of Redux are listed below:

  • Predictability of outcome – Since there is always one source of truth, i.e. the store, there is no confusion about how to sync the current state with actions and other parts of the application.
  • Maintainability – The code becomes easier to maintain with a predictable outcome and strict structure.
  • Server-side rendering – You just need to pass the store created on the server, to the client side. This is very useful for initial render and provides a better user experience as it optimizes the application performance.
  • Developer tools – From actions to state changes, developers can track everything going on in the application in real time.
  • Community and ecosystem – Redux has a huge community behind it which makes it even more captivating to use. A large community of talented individuals contribute to the betterment of the library and develop various applications with it.
  • Ease of testing – Redux’s code is mostly functions which are small, pure and isolated. This makes the code testable and independent.
  • Organization – Redux is precise about how code should be organized, this makes the code more consistent and easier when a team works with it.

Conclusion

In this note series, We understood about the React Redux Concepts in ReactJS.

Thanks for reading ! I hope you enjoyed and learned about React Redux Concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

A Short Note – Shadow DOM vs Virtual DOM In ReactJS

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Shadow DOM vs Virtual DOM In ReactJS).

In this note series, we will understand about the difference between Shadow DOM and Virtual DOM in ReactJS. We discuss the key differences between the virtual DOM and the shadow DOM.

So Let’s begin.

The shadow DOM and virtual DOM are both fundamental to progressive web frameworks like Angular, Vue, and React. While the shadow DOM encapsulates the implementation of custom web components, the virtual DOM is used to differentiate changes and more effectively re-render UIs.


What is the Virtual DOM ?

The virtual DOM is an in-memory representation of the real DOM. Popular UI libraries like React and Vue implement a virtual DOM to more efficiently re-render UI components based on a “diffing” process. By comparing changes between a virtual DOM and the real DOM, rendering engines can more efficiently determine what actually needs to be updated. This avoids unnecessary redrawing of DOM nodes as only elements that have changed are redrawn. Without the virtual DOM, every element is redrawn regardless of whether or not it has changed. This adds a huge performance boost to DOM manipulation since redrawing elements is an expensive process.


What is the Shadow DOM ?

The shadow DOM is a way of encapsulating the implementation of web components. Using the shadow DOM, you can hide the implementation details of a web component from the regular DOM tree. A popular example is the HTML5 slider input. While the regular DOM recognizes this as a simple <input/> tag, there is underlying HTML and CSS that make up the slide feature. This sub-tree of DOM nodes is hidden from the main DOM to encapsulate the implementation of the HTML5 slider. Additionally, the CSS properties for the slider are isolated from the rest of the DOM. This provides an isolated scope that prevents the component’s styles from overriding other CSS properties defined elsewhere.

The isolated scope provided by the shadow DOM results in performance benefits. By isolating the CSS properties for a custom web component, the browser can more accurately determine what needs to be updated when the DOM is manipulated.


Shadow DOM vs Virtual DOM

While the shadow DOM and virtual DOM are seemingly similar in their creation of separate DOM instances, they are fundamentally different. The virtual DOM creates an additional DOM. The shadow DOM simply hides implementation details and provides isolated scope for web components.


Conclusion

In this note series, We understood about the Shadow DOM vs Virtual DOM In ReactJS. We conclude that both the shadow DOM and virtual DOM have played a key role in the development of progressive web frameworks. While both add performance benefits, the virtual DOM is used to efficiently redraw UIs whereas the shadow DOM encapsulates the implementation of custom web components.

Thanks for reading ! I hope you enjoyed and learned about Shadow DOM Vs Virtual DOM Concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

ReactJS – How is Virtual DOM Valuable For React Performance?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, we will understand about Virtual DOM Working structure in ReactJS. We will analyse below topics to understand the Virtual DOM Concepts in ReactJS.

  • What is Real DOM ?
  • What Issues in Real DOM ?
  • What is Virtual DOM?
  • How Virtual DOM helps to solve issue?
  • React Elements Vs React Components in Virtual DOM
  • Real DOM Vs Virtual DOM

A famous quote about learning is :

” An investment in knowledge pays the best interest.”

So Let’s begin.


Real DOM

DOM stands for Document Object Model and is an abstraction of a structured text. For web developers, this text is an HTML code, and the DOM is simply called HTML DOMElements of HTML become nodes in the DOM.

So, while HTML is a text, the DOM is an in-memory representation of this text.

Compare it to a process being an instance of a program. You can have multiple processes of the same one program, just like you can have multiple DOMs of the same HTML (e.g. the same page loaded on many tabs).

The HTML DOM provides an interface (API) to traverse and modify the nodes. It contains methods like getElementById or removeChild. We usually use JavaScript language to work with the DOM, because… Well, nobody knows why :).

So, whenever we want to dynamically change the content of the web page, we modify the DOM:

#!javascript
var item = document.getElementById("myLI");
item.parentNode.removeChild(item);

document is an abstraction of the root node, while getElementByIdparentNode and removeChild are methods from HTML DOM API.


Issues

The HTML DOM is always tree-structured – which is allowed by the structure of HTML document. This is cool because we can traverse trees fairly easily. Unfortunately, easily doesn’t mean quickly here.

The DOM trees are huge nowadays. Since we are more and more pushed towards dynamic web apps (Single Page Applications – SPAs), we need to modify the DOM tree incessantly and a lot. And this is a real performance and development pain.

Consider a DOM made of thousands of divs. Remember, we are modern web developers, our app is very Specific. We have lots of methods that handle events – clicks, submits, type-ins… A typical jQuery-like event handler looks like this:

  • find every node interested on an event
  • update it if necessary

Which has two problems:

  1. It’s hard to manage. Imagine that you have to tweak an event handler. If you lost the context, you have to dive really deep into the code to even know what’s going on. Both time-consuming and bug-risky.
  2. It’s inefficient. Do we really need to do all this findings manually? Maybe we can be smarter and tell in advance which nodes are to-be-updated?

Once again, React comes with a helping hand. The solution to problem 1 is declaratives. Instead of low-level techniques like traversing the DOM tree manually, you simple declare how a component should look like. React does the low-level job for you – the HTML DOM API methods are called under the hood. React doesn’t want you to worry about it – eventually, the component will look like it should.

But this doesn’t solve the performance issue. And this is exactly where the Virtual DOM comes into action.


Virtual DOM

In React, for every DOM object, there is a corresponding “virtual DOM object.” A virtual DOM object is a representation of a DOM object, like a lightweight copy.

A virtual DOM object has the same properties as a real DOM object, but it lacks the real thing’s power to directly change what’s on the screen.

A virtual DOM is a lightweight JavaScript object which originally is just the copy of the real DOM. It is a node tree that lists the elements, their attributes and content as Objects and their properties. React’s render function creates a node tree out of the React components. It then updates this tree in response to the mutations in the data model which is caused by various actions done by the user or by the system.

Manipulating the DOM is slow. Manipulating the virtual DOM is much faster, because nothing gets drawn onscreen. Think of manipulating the virtual DOM as editing a blueprint, as opposed to moving rooms in an actual house.


How it helps

When you render a JSX element, every single virtual DOM object gets updated.

This sounds incredibly inefficient, but the cost is insignificant because the virtual DOM can update so quickly.

Once the virtual DOM has updated, then React compares the virtual DOM with a virtual DOM snapshot that was taken right before the update.

By comparing the new virtual DOM with a pre-update version, React figures out exactly which virtual DOM objects have changed. This process is called “diffing.”

Once React knows which virtual DOM objects have changed, then React updates those objects, and only those objects, on the real DOM. In our example from earlier, React would be smart enough to rebuild your one checked-off list-item, and leave the rest of your list alone.

This makes a big difference! React can update only the necessary parts of the DOM. React’s reputation for performance comes largely from this innovation.

In summary, here’s what happens when you try to update the DOM in React:

  1. The entire virtual DOM gets updated.
  2. The virtual DOM gets compared to what it looked like before you updated it. React figures out which objects have changed.
  3. The changed objects, and the changed objects only, get updated on the real DOM.
  4. Changes on the real DOM cause the screen to change.


ReactElement Vs ReactComponent

When we are talking about the virtual DOM, it’s important to see the difference between these two.


ReactElement

This is the primary type in React. React docs say:

ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.

ReactElements lives in the virtual DOM. They make the basic nodes here. Their immutability makes them easy and fast to compare and update. This is the reason of great React performance.

What can be a ReactElement? Almost every HTML tag – divtablestrong.

Once defined, ReactElements can be render into the “real” DOM. This is the moment when React ceases to control the elements. They become slow, boring DOM nodes:

#!javascript
var root = React.createElement('div');
ReactDOM.render(root, document.getElementById('example'));
// If you are surprised by the fact that `render` 
// comes from `ReactDOM` package, see the Post Script.

JSX compiles HTML tags to ReactElements. So this is equivalent to the above:

#!javascript
var root = <div />;
ReactDOM.render(root, document.getElementById('example'));

Once again – ReactElements are the basic items in React virtual DOM. However, they are stateless, therefore don’t seem to be very helpful for us, the programmers. We would rather work on the class-like pieces of HTML, with kind-of-variables and kind-of-constants – don’t we? And here we come to…


ReactComponent

What differs ReactComponent from ReactElement is – ReactComponents are stateful.

We usually use React.createClass method to define one:

#!javascript
var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        Hello, world! I am a CommentBox.
      </div>
    );
  }
});

Your HTML-like blocks returned from render method can have a state. And the best thing is whenever the state changes, the component is re-rendered:

#!javascript
var Timer = React.createClass({
  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
});

ReactComponents turned out to be a great tool for designing dynamic HTML. They don’t have the access to the virtual DOM, but they can be easily converted to ReactElements:

#!javascript
var element = React.createElement(MyComponent);
// or equivalently, with JSX
var element = <MyComponent />;


What makes the difference?

ReactComponents are great. They are easy to manage. But they have no access to the virtual DOM – and we would like to do as much as possible there.

Whenever a ReactComponent is changing the state, we want to make as little changes to the “real” DOM as possible. So this is how React deals with it. The ReactComponent is converted to the ReactElement. Now the ReactElement can be inserted to the virtual DOM, compared and updated fast and easily. How exactly – well, that’s the job of the diff algorithm. The point is – it’s done faster than it would be in the “regular” DOM.

When React knows the diff – it’s converted to the low-level (HTML DOM) code, which is executed in the DOM. This code is optimised per browser.


Real DOM Vs Virtual DOM

Now we can say about the difference between Real DOM and Virtual DOM that :

  • Real DOM is a language-neutral interface allowing programs and scripts to dynamically access and update multiple objects like content, structure, and style of a document. while Virtual DOM is a collection of modules designed to provide a declarative way to represent the DOM for an application.
  • The Real DOM represents the document as nodes and objects, while A virtual DOM object is a representation of a DOM object, like a lightweight copy.
  • Real DOM is an object-oriented representation of a web page, modified with a scripting language like JavaScript , while Virtual DOM is ideal for mobile-first applications.
  • Real DOM updates Slow while Virtual DOM updates faster.
  • Real DOM can directly update HTML, while Virtual DOM can’t directly update HTML.
  • Real DOM creates a new DOM if element updates, while Virtual DOM updates the JSX if element updates.
  • With Real DOM, DOM manipulation is very expensive, while DOM manipulation is very easy with Virtual DOM.
  • Real DOM includes Too much of memory wastage, while Virtual DOM includes no memory wastage.

That’s all about in this article.


Conclusion

In this article, We understood about about Virtual DOM Working structure in ReactJS.

Thanks for reading ! I hope you enjoyed and learned about the Virtual DOM concepts in ReactJS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING!!???

A Short Note – Stateless Component vs Pure Component in React Application

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Stateless Component vs Pure Component in React Application).

In this note series, we will understand about the difference between Stateless Component and Pure Component in React Application. We will be discussing how both components compare performance wise, developer experience and how both will fit into our ReactJS production project.


So Let’s Begin.


Stateless Component

STATELESS COMPONENT declared as a function that has no state and returns the same markup given the same props.

A quote from the React documentation:

These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate. However, we may still specify .propTypes and .defaultProps by setting them as properties on the function, just as we would set them on an ES6 class.


Pure Component

PURE COMPONENT is one of the most significant ways to optimize React applications. The usage of Pure Component gives a considerable increase in performance because it reduces the number of render operation in the application.


Example

Let’s look at the performance aspect of both components.

class Welcome extends React.PureComponent {  
  render() {
    return <h1>Welcome</h1>
  }
}

Hello = () => {
  return <h1>Hello</h1>;
}

So above there is an example of a very simple Welcome Pure Component and Hello Stateless Component. When we use these two in our Parent Component, we will see Hello will re-render whenever Parent Component will re-render but Welcome Component will not.

This is because PureComponent changes the life-cycle method shouldComponentUpdate and adds some logic to automatically check whether a re-render is required for the component. This allows a PureComponent to call the method render only if it detects changes in state or props.


When to use Pure Components?

Suppose we are creating a dictionary page in which we display the meaning of all the English words starting with A. Now we can write a component which takes a word and its meaning as props and return a proper view. And suppose us using pagination to display only 10 words at a time and on scroll asking for another 10 words and updating the state of the parent component. Pure Components should be used in this case as  it will avoid rendering of all the words which rendered in previous API request.

Also in cases where we want to use lifecycle methods of component then we have to use Pure components as stateless components don’t have lifecycle methods.


When to use Stateless Components?

Suppose we want to create a label with some beautiful UI which will be used to rate the credibility of a profile like BEGINNER, MODERATE, EXPERT. Since its a very small component whose re-render will hardly make any difference and creating a new component for such a small case will be time-consuming. Also if we keep making components for very small-small view, soon we will end up with so many components and it will be hard to manage when working with a big project. Also always keep in mind Pure Component comes with peculiarities of the shallowEqual.


Conclusion

In this note series, We understood about the difference between Stateless Component and Pure Component in React application.

Thanks for reading ! I hope you enjoyed and learned about the Stateless Component and Pure Component differences in React application. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

A Short Note – How to Improve the Performance of React Native App?

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (How to Improve the Performance of React Native App?).

In this note series, we will understand about the pro tips to improve the performance of the React Native app. There are so many ways to do this but here we will discuss few most preferred ways as below:

  • Use of shouldComponentUpdate method of react-native life cycle
  • Pure Components of React
  • Use Memo from Hooks API
  • Build the module with native whenever it is possible
  • Remove the console logs before building the application
  • Reduce Application size


So Let’s begin.


1. Use of shouldComponentUpdate method of react-native life cycle

Using shouldComponentUpdate method, we can reduce un-necessary re-rendering of components.

shouldComponentUpdate returns the boolean value and according to that components will re-render. For example, if it returns true then it will re-render and if it returns false then it will not re-render component.

So, on state update or on new props to the component, this method will be called with two arguments called nextState and nextProps. So, we can compare the new props and state with the previous ones. And according to our business logic requirements, we can use the boolean to render the component again.


2. Pure Components of React

The pure component of React helps to render only the specific props that have been changed or the state has updated.

For example, if we are using a flatlist which is rendering 1000 rows. Now, on every re-render, that 1000 data will be rendered again.

Using Flatlist in the pure component, we can ensure that only the change on required props components will re-render again.


3. Use Memo from Hooks API

React Hooks provide the life cycle of components to functions.

Memo from react helps to do a shallow comparison on upcoming changes. So, it allows re-rendering functions only if the props get changed.


4. Build the module with the native driver whenever it is possible

Here, We are not talking about not using React Native. Sometimes, we have to use some features which can be done by the native more efficiently. We build that module in native one and can use the feature from the React Native by creating a bridge.


5. Remove the console logs before building the application

It has been identified that the console logs are taking some amount of time for logging purposes. So, it is good to use at the time of development but in the production build, it should be removed which will help to improve the performance of the app which we will realize while using it.


6. Reduce Application size

In React Native, we use external libraries and components form libraries so it impacts application size.

To reduce the size, we have to optimize the resources, use ProGaurd, create different app sizes for different device architectures, and make sure to compress the graphics elements, i.e. images.

The components on the JavaScript side use a bridge to communicate with the Native side. Reduce the load on the bridge and improve the app’s performance.


Conclusion

In this note series, we understood about the pro tips to improve the performance of the React Native app.

Thanks for reading! I hope you enjoyed and learned about the React Native app Performance Improvement pro tips. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React Native as below links :

If you have any comments, questions, or think I missed something, leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

A Short Note – Functional vs Class Components in React Native

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Functional vs Class Components in React Native).

In this note series, we will understand about the difference between Functional and Class Components in React Native.

So Let’s begin.

In React Native, there are two main types of components that make up an application: functional components and class components. These are structured the same as they would be in a regular React app for the web.


Class Components vs Functional Components


1. Syntax

Class components are JavaScript ES2015 classes that extend a base class from React called Component and create a render function that returns a React element. This requires more code as well.

The Class Component in React Native

class App extends Component {
    render () {
        return (
            <Text>Hello World!</Text>
        )
    }
}
export default App;

A Functional Component looks like a plain JavaScript function and are sometimes called stateless components.

The Functional Component in React Native

const App = () =>{
	return (
	  <Text>Hello World!</Text>
	)
}
export default App;


2. State

In Class components, there is a way to store and manage state built in to React Native. This gives the class App access to the React life cycle methods like render as well as state/props functionality from the parent. While managing the state in classes, we use setState and this.state to set and get the state, respectively.

State in Class Component

mport React from 'react';
import {Text, View} from 'react-native';

class App extends React.Component {
	constructor(props){
		super(props);
		this.state = { value:0};
		setInterval(() =>{
			this.setState({ value: this.state.value + 1});
		}, 1000);
	}

	render() {
		return (
			<View>
				<Text>{'State Value =>' + this.state.value}</Text>
			</View>
		);

	}
}

export default App;

But in the functional component, we have useState hook after the update of React 16.8. They don’t manage their own state by React Native.

State in Functional Component

import React, { useState } from 'react';
import {Text, View} from 'react-native';

const App = () => {
		let [value, setValue] = useState(0);
		
		setInterval(() =>{
			setValue(value + 1);
		}, 1000);
	
		return (
			<View>
				<Text>{'State Value =>' + value}</Text>
			</View>
		);
};

export default App;


3. Lifecycle Methods/Hooks

Another most important difference in Class and Functional Component is the life cycle methods, or we can say Lifecycle Hooks. We all know how important is the Lifecycle methods while developing any React Native application. Life cycle methods give us the power to control the data and application flow on different activities. We are very much familiar with the class component Lifecycle methods but in case of Functional Components we have to manage all this with the help of useEffect hook.

Example of Lifecycle Methods for Class Component

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    }
  }

  componentDidMount() {
    const interval = setTimeout(() => {
      this.setState({ count: this.state.count + 1 });
    }, 1000);
    return () => {
      clearInterval(this.interval);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <Text> Count incremented {this.state.count} times</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Example of useEffect Hook for Functional Component

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount
  useEffect(() => {
    const interval = this.setTimeout(() => {
      setCount(count + 1);
    }, 1000);
    return () => {
      clearInterval(this.interval);
    }
  }, []);

  return (
    <View style={styles.container}>
      <Text> Count incremented {count} times</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});


Conclusion

In this note series, we understood about the difference between Functional and Class Components in React Native. We conclude that :

  • Class components are used as container components to handle state management and wrap child components.
  • Functional components are just used for display purposes – these components call functions from parent components to handle user interactions or state updates. 

Thanks for reading! I hope you enjoyed and learned about Functional Vs Class Components Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React Native as below links :

If you have any comments, questions, or think I missed something, leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

Exit mobile version