首页 > 编程问答 >React Native:尝试使用手势处理使文本组件可拖动时出现渲染错误

React Native:尝试使用手势处理使文本组件可拖动时出现渲染错误

时间:2024-06-07 14:53:12浏览次数:22  
标签:javascript react-native mobile react-native-reanimated react-native-gesture-hand

我正在 React Native 应用程序中开发一项照片编辑功能,用户可在其中添加可拖动的文本覆盖。 我使用钩子来管理文本块的位置,并通过手势处理来更新它们。 但是,当我尝试在手势过程中更新这些文本元素的位置(例如拖动)时、 我遇到了一个呈现错误:"呈现的钩子比上一次呈现时多。

我怀疑该问题可能与钩子或手势处理程序的实现方式有关。我如何才能正确更新文本块的位置,而不会遇到此呈现错误?

 {textBlocks.map((block, index) => (
                      文本
                        onLayout={(event) => {
                          const { width, height }= event.nativeEvent.layout;
                          setTextSize({ width, height });
                        }}
                        key={index}
                        style={[styles.addedTextStyle, { left: block.x, top: block.y, color: block.color, fontSize: fontSize, }]}>;
                        {block.text}
                      </Text>;
                    ))}
    rn-draggable

  • 拖动文本编辑器
  • 链式重现 + 动画视图
  • rn-draggable
  • rn-drag-text-editor
  • rn-gesture-handler (为每个文本添加监听器)
  • 我尝试了一些方法,以使文本添加到屏幕后可拖动。 每个方法都会导致错误。


    遇到的 "呈现的钩子比上一次呈现时多" 错误,通常表示在组件渲染过程中以某种方式创建了新的状态或更改了组件树的结构,这违反了 React 的钩子规则。

    以下是可能导致此问题的一些常见原因以及如何解决它们:

    1. 在循环、条件语句或嵌套函数中调用 Hook

    确保没有在循环、条件语句或嵌套函数中直接调用 useState 或其他 Hook。 Hook 应该始终在组件的顶层调用,并且它们的调用顺序应该在每次渲染时保持一致。

    错误示范:

    {textBlocks.map((block, index) => {
      // 错误:在循环中调用 useState
      const [fontSize, setFontSize] = useState(16); 
    
      return (
        <Text 
          key={index} 
          onLayout={(event) => {
            const { width, height } = event.nativeEvent.layout;
            setFontSize({ width, height });
          }} 
          style={[styles.addedTextStyle, { left: block.x, top: block.y, color: block.color, fontSize: fontSize }]}
        >
          {block.text}
        </Text>
      );
    })}
    

    正确示范:

    // 将 fontSize 状态提升到循环外
    const [fontSizes, setFontSizes] = useState({});
    
    {textBlocks.map((block, index) => (
      <Text 
        key={index} 
        onLayout={(event) => {
          const { width, height } = event.nativeEvent.layout;
          // 更新对应文本块的 fontSize
          setFontSizes(prevSizes => {
            return { ...prevSizes, [index]: { width, height } };
          });
        }} 
        style={[styles.addedTextStyle, { left: block.x, top: block.y, color: block.color, fontSize: fontSizes[index] }]}
      >
        {block.text}
      </Text>
    ))}
    

    2. 在组件渲染完成后更新状态

    确保没有在组件渲染完成后立即更新状态。 例如,在 useEffect 中使用不带依赖项数组的 setState 可能会导致无限循环,从而引发此错误。

    错误示范:

    useEffect(() => {
      // 错误:没有依赖项数组,每次渲染后都会执行
      setTextBlocks(updatedTextBlocks); 
    }, []); 
    

    正确示范:

    useEffect(() => {
      // 只有当 updatedTextBlocks 改变时才会执行
      setTextBlocks(updatedTextBlocks); 
    }, [updatedTextBlocks]); 
    

    3. 使用不兼容的库版本

    确保使用的所有库(例如 react-native-gesture-handler rn-draggable 等)版本兼容。 不兼容的版本可能会导致意外的行为,包括此错误。

    其他建议:

    • 简化组件: 尝试将的组件分解为更小的、更易于管理的组件,以隔离问题。
    • 使用 React Developer Tools: React Developer Tools 浏览器扩展程序可以帮助检查组件树、状态和 props,这对于调试此类问题非常有用。

    请提供更多关于如何使用钩子和手势处理程序的代码,以便我提供更具体的帮助。 特别是,请分享以下代码片段:

    • 管理 textBlocks 状态的代码
    • 处理手势并更新文本块位置的代码
    • 正在使用的任何外部库的版本

    有了这些信息,我就可以更准确地诊断问题并提供解决方案。

    标签:javascript,react-native,mobile,react-native-reanimated,react-native-gesture-hand
    From: 78548301

    相关文章

    • 螺旋转动,矩阵的舞蹈:JavaScript中实现螺旋矩阵遍历算法
      螺旋转动,矩阵的舞蹈:JavaScript中实现螺旋矩阵遍历算法基础概念:什么是螺旋矩阵?核心算法解析示例一:基础螺旋矩阵遍历算法解析进阶技巧示例二:动态生成螺旋矩阵技巧点实战与性能优化问题与解决:大矩阵处理结语与讨论在编程的奇幻世界里,数组与矩阵是构筑数字城堡的基石......
    • 数组大扫雷行动:JavaScript中的高效移除指定元素
      数组大扫雷行动:JavaScript中的高效移除指定元素基本概念:移除元素,何为?方法一:splice()大法方法二:filter()轻功功能使用角度与技巧案例一:简单移除案例二:条件移除实战分析遇到的坑与对策结语与讨论在JavaScript编程的征途中,数组是我们的常伴,而“移除元素”这一任务,则像......
    • 【JS封装-数组操作】强化编程实践:精选JavaScript函数封装集锦-关于数组操作(数组去重、
      目录数组去重数组快速排序过滤数组映射数组数组扁平化数组求和数组最大值数组最小值数组切片数组乱序(洗牌算法)数组去重/***去除数组中的重复项。*@param{Array}array要去重的数组。*@returns{Array}去重后的数组。*/functionuniqueArray(array......
    • JavaScript第十一讲:DOM编程“事件”
      前言当涉及到DOM(DocumentObjectModel)的事件时,JavaScript提供了许多内置的事件处理器,用于处理用户在网页上执行的各种操作。1.焦点事件当元素获得或失去焦点时触发。onfocus:当元素获得焦点时触发。onblur:当元素失去焦点时触发。//假设有一个输入框<inputtype="......
    • 【JavaScript函数】
      函数:是被设计为执行特定任务的代码块。作用:代码重用,结构清晰1.1、定义函数定义函数有两种方法:函数声明和函数表达式:1.1.1、函数声明解释:这里声明一个函数f,并传入一个参数a,当函数执行以后,通过return关键字返回了a+1的值。1.1.2、函数表达式通过定义一个匿......
    • 微前端学习笔记(3):前端沙箱之JavaScript的sandbox(沙盒/沙箱)
      sandboxSandbox(沙盒/沙箱)的主要目的是为了安全性,以防止恶意代码或者不受信任的脚本访问敏感资源或干扰其他应用程序的执行。通过在沙盒环境中运行,可以确保代码的行为被限制在一个安全的范围内,防止其超出预期权限进行操作。沙箱(Sandbox)是一种安全机制,目的是让程序运行在一个相对......
    • 【网络安全的神秘世界】JavaScript
      ......
    • 【JavaScript详解】Day02
      JavaScript基础-第2天理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力运算符语句综合案例运算符算术运算符数字是用来计算的,比如:乘法*、除法/、加法+、减法-等等,所以经常和算术运算符一起。算术运算......
    • JavaScript-变量
      JavaScript-1.变量1.js引入方式a.内部脚本:将Js代码定义在script标签中 <script>window.alert("HELLOJS")//将我们指定的入参文案以弹框的形式显示出来document.write("hellojs!")//将入参文案写入到当前的HTML内容中console.log("helloj......
    • JavaScript-数据转换
      JavaScript-数据类型转换和运算符数据类型js中的数据类型分为:原始类型和引用类型,具体有如下类型:数据类型描述number数字(整数、小数、NaN(NotaNumber))string字符串,单双引皆可boolean布尔。true,falsenull对象为空undefined当声明的变量未初始化时......