Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tried to register two views with same name

I know this kind of question has been asked before but they are related to third party libraries, mine is related to requireNativeComponent

I have created a React Native Component from a Native iOS component

Here is my iOS code

CanvasView File

class CanvasView: UIView {
    
    var lines = [[CGPoint]]()
    
    override init(frame: CGRect) {
        super.init(frame:frame)
        backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        
        context.setStrokeColor(#colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1))
        context.setLineWidth(10)
        context.setLineCap(.butt)
        
        lines.forEach { (line) in
            for(i,p) in line.enumerated() {
                if i == 0 {
                    context.move(to: p)
                } else {
                    context.addLine(to: p)
                }
            }
        }
        
        
        
        context.strokePath()
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        lines.append([CGPoint]())
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let point = touches.first?.location(in: nil) else {
            return
        }
        
        
        
        guard var lastLine = lines.popLast() else {return }
        lastLine.append(point)
        lines.append(lastLine)
        setNeedsDisplay()
    }
}

Canvas.swift File

import Foundation

@objc(Canvas)
class Canvas: RCTViewManager {
  override func view() -> UIView! {
    return CanvasView()
  }
  
  override class func requiresMainQueueSetup() -> Bool {
    return true
  }
  
}

Canvas.m file

#import <Foundation/Foundation.h>
#import "React/RCTViewManager.h"


@interface RCT_EXTERN_MODULE(Canvas, RCTViewManager)
@end

Here is my JS code

const Canvas = requireNativeComponent('Canvas');

const App = () => {
 return (
    <View style={styles.container}>
      <Canvas style={styles.bottom} />
    </View>
  );}

the code works fine, but even when I do some change in my react native code and do command+s to do fast refresh I keep getting error saying Tried to register two views with the same name Canvas, but when I run npx react-native run-ios, the code works fine. So all in all hot reloading or fast refresh is not supported when I include Native component created by me even though I am not changing the native component. I can understand if I change something in iOS swift or objective c code then I need to re-run npx react-native run-ios but even after no changes in iOS side and doing only changes in JS side I keep getting this error. There are not two views with same name of Canvas in my project. I also tried clearing watchman, deleting package.json and reinstalling npm modules and pod

Same issue happens on android side as well

like image 238
Pritish Avatar asked Aug 15 '20 10:08

Pritish


2 Answers

When fast refresh runs, this line is executed again:

const Canvas = requireNativeComponent('Canvas');

And that's where the "Tried to register two views with same name" error comes from. There are a couple of ways to fix this.

  1. Move that line to its own file and export it: export const Canvas = requireNativeComponent('Canvas');, and then import it where you want to use it. You'll still get the same error if you save the new file that contains this line, but you typically won't change this file so it usually won't be an issue.
  2. Guard against the native component being registered (via requireNativeComponent) multiple times. It's a bit ugly, but you can do this by storing it in the global scope: const Canvas = global['CanvasComponent'] || (global['CanvasComponent'] = requireNativeComponent('Canvas'));
like image 121
Ryan Tremblay Avatar answered Nov 30 '22 08:11

Ryan Tremblay


I think that issue is not from the native module. it is from register the same package two times.

go to project root and run the below command

npm list

enter image description here

find the package by ctrl+f which you think that is creating problem like Canvas

remove that second package which is using the same package which is creating problem like Canvas

or

you can fork that package and add that package in peer dependency and use that package from your git

like image 45
Muhammad Numan Avatar answered Nov 30 '22 07:11

Muhammad Numan