react-native-skia: useComputedValue leads to Internal React Error due to useEffect cleanup

Description

I’ve built my first component using Skia. Unfortunately, I’m getting render errors undefined is not a function from the useComputedValue hook where I’m calculating the positions of the objects based on the screen size.

I’m getting the following error messages.

ERROR  Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.

Error message: 

TypeError: undefined is not a function
     in Background (created by Index)

Version

0.1.193

Steps to reproduce

Render the component provided below. The bug appears when the component get’s unloaded (e.g. because I update the component and trigger a hot-reload)

Snack, code example, screenshot, or link to a repository

import { memo } from "react";
import { View } from "react-native";
import {
  Blur,
  Canvas,
  ColorMatrix,
  FractalNoise,
  Group,
  Oval,
  Rect,
  SweepGradient,
  rect,
  useComputedValue,
  useValue,
  vec,
} from "@shopify/react-native-skia";

export const Background = memo(function Background() {
  const size = useValue({ width: 0, height: 0 });
  const fullRect = useComputedValue(() => {
    return rect(0, 0, size.current.width, size.current.height);
  }, [size]);
  const blob1 = useComputedValue(() => {
    return rect(
      0 - size.current.width / 12,
      0 - size.current.height / 30,
      size.current.width / 2,
      size.current.height / 3,
    );
  }, [size]);
  const centerBlob1 = useComputedValue(() => {
    return vec(
      blob1.current.width / 2 + blob1.current.x,
      blob1.current.height / 2 + blob1.current.y,
    );
  }, [blob1]);
  const blob2 = useComputedValue(() => {
    return rect(
      (size.current.width * 1.2) / 2,
      (size.current.height * 2.2) / 3,
      size.current.width / 2,
      size.current.height / 3,
    );
  }, [size]);
  const centerBlob2 = useComputedValue(() => {
    return vec(
      blob2.current.width / 2 + blob2.current.x,
      blob2.current.height / 2 + blob2.current.y,
    );
  }, [blob1]);
  return (
    <View className="absolute -z-50 flex h-full w-full bg-darkGrey">
      <Canvas className="bg-darkGrey" style={{ flex: 1 }} onSize={size}>
        <Group blendMode="multiply">
          <Blur blur={50} />
          <Group
            origin={centerBlob1}
            transform={[
              {
                rotate: -1,
              },
            ]}
          >
            <Oval rect={blob1}>
              <SweepGradient c={centerBlob1} colors={["#0D28F2", "#FBC02D"]} />
            </Oval>
          </Group>
          <Group
            origin={centerBlob2}
            transform={[
              {
                rotate: -0.2,
              },
            ]}
          >
            <Oval rect={blob2}>
              <SweepGradient
                c={centerBlob2}
                colors={["#FF5A5A", "#0D28F2", "#FF5A5A"]}
                positions={[0, 0.1, 1]}
              />
            </Oval>
          </Group>
        </Group>
        <Group blendMode="darken" opacity={1}>
          <ColorMatrix
            matrix={[
              1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0.03, 0,
            ]}
          />
          <Blur blur={1} />
          <Rect rect={fullRect}>
            <FractalNoise freqX={0.2} freqY={0.2} octaves={4} />
          </Rect>
        </Group>
      </Canvas>
    </View>
  );
});

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17

Most upvoted comments

this looks very strange maybe in the meantime you can use { x, y} for the point and {x,y,width} for rect (JS objects).