5

我知道以前有人问过这种问题,但它们与第三方库有关,我的与requireNativeComponent

React Native从本机iOS组件创建了一个组件

这是我的iOS代码

CanvasView 文件

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文件

import Foundation

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

Canvas.m文件

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


@interface RCT_EXTERN_MODULE(Canvas, RCTViewManager)
@end

这是我的JS代码

const Canvas = requireNativeComponent('Canvas');

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

代码工作正常,但即使我对我的反应本机代码进行了一些更改并执行命令+s,fast refresh我仍然会收到错误消息Tried to register two views with the same name Canvas,但是当我运行时npx react-native run-ios,代码工作正常。hot reloading or fast refresh因此,即使我没有更改本机组件,当我包含我创建的本机组件时,总而言之不受支持。我可以理解如果我在 iOS swift 或客观 c 代码中更改某些内容,那么我需要重新运行 npx react-native run-ios,但即使在侧面没有更改iOS并且只在JS侧面进行更改后,我仍然会收到此错误。我的项目中没有两个同名的视图Canvas。我还尝试清除watchman、删除package.json和重新安装npm模块和pod

同样的问题也发生在android一边

4

3 回答 3

9

当快速刷新运行时,再次执行此行:

const Canvas = requireNativeComponent('Canvas');

这就是“试图注册两个具有相同名称的视图”错误的来源。有几种方法可以解决这个问题。

  1. 将该行移至其自己的文件并导出:export const Canvas = requireNativeComponent('Canvas');,然后将其导入您要使用的位置。如果您保存包含此行的新文件,您仍然会收到相同的错误,但您通常不会更改此文件,因此它通常不会成为问题。
  2. 防止本地组件被(通过requireNativeComponent)多次注册。这有点难看,但是您可以通过将其存储在全局范围内来做到这一点:const Canvas = global['CanvasComponent'] || (global['CanvasComponent'] = requireNativeComponent('Canvas'));
于 2020-12-02T17:38:12.853 回答
1

我认为这个问题不是来自本机模块。它来自两次注册同一个包。

转到项目根目录并运行以下命令

npm list

在此处输入图像描述

通过ctrl+f找到您认为会产生问题的包Canvas

删除使用相同包的第二个包,该包会产生类似问题Canvas

或者

您可以分叉该包并将该包添加到对等依赖项中,并从您的 git 使用该包

于 2020-08-17T20:50:23.760 回答
0

所以我遇到了这个问题,直到我意识到应用程序在快速刷新时抛出错误非常有意义,因为本机 UI 无法在运行时热重新加载。你可以更新你的 React 组件,因为你的组件可以在运行时重新挂载,从而热重新加载。

如果您尝试刷新 Swift 或 Obj-C,则您正在创建数据的第二个实例,因此在此之前会引发错误。

快速的解决方案是在运行 Metro 捆绑器的终端上按键盘上的“r”。无论您在哪里使用本机组件,都必须这样做。

于 2021-07-21T21:33:22.583 回答