alabsi91 / reanimated-color-picker

A Pure JavaScript Color Picker for React Native
https://alabsi91.github.io/reanimated-color-picker/
MIT License
234 stars 16 forks source link

function passed to `onChange` prop of `ColorPicker` doesn't get executed #79

Closed majih93 closed 3 months ago

majih93 commented 3 months ago

Description

Hi, thank you for the nice library.

I am trying to use the Panel5 component to allow users to pick colors, but the function passed to the onChange prop of the ColorPicker wrapper doesn't execute.

I am using react-native-reanimated version 2.8.0, and have found out that when I upgrade react-native-reanimated to a version higher than 3.0.0, the passed function gets executed as expected.

However, due to other libraries depending on react-native-reanimated, it is difficult for me to upgrade the version react-native-reanimated.

additional information

In the ColorPicker component in your library, the below changes do make the component work as I have expected. But I have no deep understanding of the code. Just adding this in case it might help :)

      // onGestureChange function inside ColorPicker.tsx
    const onGestureChange = (color?: SupportedColorFormats) => {
      'worklet';

      if (!onChange) return;
      const colorObject = returnedResults(color);

      // executing runOnJS makes it work, but I have no understanding of why..
      runOnJS(onChange)(colorObject)

      // below is the original code,
      // try {
      //   // run on the UI thread
      //   onChange(colorObject);
      // } catch (error) {
      //   // run on the JS thread
      //   runOnJS(onChange)(colorObject);
      // }
    };

Steps to reproduce

  1. install react-native-reanimated version 2.8.0, react-native-gesture-handler version 2.10.1 with reanimated-color-picker version 3.0.3
  2. pass a function to the onChange prop of the ColorPicker wrapper component
  3. add Panel5 as a child to the Colorpicker wrapper.
  4. press any color in the Panel5 component -> doesn't trigger function passed to the onChange prop, making it impossible to get the pressed color value.

Snack or a link to a repository

No response

Reanimated Color Picker version

3.0.3

React Native version

0.66.4

React Native Reanimated version

2.8.0

React Native Gesture Handler version

2.10.1

Platforms

iOS

JavaScript runtime

JSC

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

Debug mode

alabsi91 commented 3 months ago

Hey, thanks for reporting this. The code in the library is designed to make the onChange property accept both worklet and non-worklet functions. Since Reanimated doesn't provide a clear way to detect a worklet, I used a try/catch block as a workaround. Please try passing a worklet function instead, and inside it, you can use runOnJS if needed. If that doesn't work, you might consider using patch-package because I can't think of a solution that works for every version of Reanimated.

majih93 commented 3 months ago

Hey,

I have tried to pass a worklet function to the onChange prop and it works! Thank you for your help.

for people who might see this, the function i have implemented is as follows:

// function passed to the `onChange` prop of `ColorPicker` wrapper component
const onSelectColor = ({ hex }) => {
    'worklet'; // making this function a worklet function did the job for me.
    console.log('pressed color', hex); // getting the color value as expected :)
};