You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Skia绘图应用状态异常:仅保留最后一条路径

React Native Skia画布无法保存多路径的问题解决

问题核心原因

  1. 闭包陷阱导致状态捕获失效:你使用的useCallback都未添加依赖数组,比如savePaths里引用了paths但未将其加入依赖,导致回调始终捕获组件初始化时的空paths数组,每次保存都是在空数组基础上新增,直接覆盖之前的状态。
  2. 临时路径用普通变量无法持久化:workingPath是普通let变量,组件每次重新渲染(比如状态更新后)都会重置该变量,逻辑上存在隐患,应该用useRef保存,因为ref.current在组件生命周期内不会被重置。
  3. 冗余的displayPaths状态:没必要将JSX元素存入状态,直接在渲染阶段映射paths数组即可,状态只负责存储数据,渲染逻辑放在render阶段更合理。

修改后的完整代码

import {
  Canvas,
  Path,
  Group,
  useTouchHandler,
} from "@shopify/react-native-skia";
import { useState, useRef, useCallback } from 'react';

export const StateTest = () => {
  // 用useRef保存临时路径,避免组件渲染时重置
  const workingPathRef = useRef<string[]>([]);

  const [paths, setPaths] = useState<string[]>([]);

  const onDrawingStart = useCallback(({ x, y }) => {
    workingPathRef.current = [`M ${x} ${y}`];
  }, []);

  const onDrawingActive = useCallback(({ x, y }) => {
    if (!workingPathRef.current) {
      return;
    }
    workingPathRef.current.push(`L ${x} ${y}`);
  }, []);

  const onDrawingFinished = useCallback(() => {
    if (!workingPathRef.current || workingPathRef.current.length === 0) {
      return;
    }
    // 用函数式更新获取最新状态,彻底规避闭包问题
    setPaths(prevPaths => [...prevPaths, workingPathRef.current.join(" ")]);
    workingPathRef.current = [];
  }, []);

  const touchHandler = useTouchHandler({
    onActive: onDrawingActive,
    onStart: onDrawingStart,
    onEnd: onDrawingFinished,
  });

  return (
    <Canvas style={{ flex: 1 }} onTouch={touchHandler}>
      <Group>
        {/* 直接在渲染阶段映射paths数组 */}
        {paths.map((p, index) => (
          <Path 
            key={index} 
            path={p} 
            color="red" 
            style="stroke" 
            strokeWidth={4} 
          />
        ))}
      </Group>
    </Canvas>
  );
};

关键修改说明

  • 替换workingPath为useRef:确保临时绘制路径在组件多次渲染中不会丢失。
  • 使用函数式更新setPaths:通过prevPaths获取最新状态,彻底避免闭包导致的旧状态引用问题,无需依赖paths。
  • 移除冗余状态与副作用:删掉displayPaths相关的状态、drawPaths函数和useEffect,直接在Canvas中渲染paths,简化逻辑。
  • 补全useCallback依赖数组:确保回调函数的稳定性,符合React Hooks的规则。

内容的提问来源于stack exchange,提问作者cbolton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:25:26