I've looked at both the PR that added a note on RunOnJS (p.s. this doesn't appear in the docs) and I've looked at the example found here. However I still get the redbox that says Tried to synchronously call function {bound dispatchAction} from a different thread....
What I'm trying to achieve, is to update local state once the animation completes.
export function someAnimation(callback?: (isCancelled: boolean) => void) {
'worklet';
return withSequence(
withTiming(1, {duration: 300, easing: Easing.linear}),
withDelay(100, withTiming(2, {duration: 500, easing: Easing.linear}, callback)),
);
}
// Inside a functional component
const [value, setValue] = React.useState(false);
// Trigger it here on first render
React.useEffect(() => {
shared.value = someAnimation(runOnJS(() => setValue(true)));
}, []);
I've tried multiple variants (based on the two links above) to no avail.
i.e.
// And then I just tried doing random stuff in hopes it works
function setTheValue() { //including const declaration
'worklet'; // and without 'worklet'
setValue(true);
}
// Also
shared.value = someAnimation(runOnJS(() => { 'worklet'; setValue(true)}));
I too have the same issue https://github.com/software-mansion/react-native-reanimated/issues/1393#issuecomment-726790287 . Also see the same issues below
I'm unable to get the above scenario working. The snippet below does work(if it helps)..
function MyComponent({ functionToCall }) {
...
const animatedStyle = useAnimatedStyle(() => {
const size = withTiming(1, { duration: 300 }, runOnJS(functionToCall));
return {
height: size,
width: size
}
})
...
}
function MainComponent() {
return (
<MyComponent
functionToCall={() => {
// Do stuff
}}
/>
);
}
You can do const size = withTiming(1, { duration: 300 }, () => runOnJS(functionToCall)())
Hi @Andarius, the code snippet here works fine. It's the snippet in OP that doesn't.
I will however try your approach on my original issue. Will report back.
Sadly no, that results in the same error. Here is what I tried.
shared.value = someAnimation(() => runOnJS(someFunction)());
Why is someAnimation a worklet ? It's called from the JS Thread
I'd say my lack of understanding worklets. I removed 'worklet', however same error.
The following works
function updateShare(){
setValue(true)
}
function callback(isCancelled: boolean){
'worklet'
runOnJS(updateShare)()
}
React.useEffect(() => {
shared.value = someAnimation(callback)
}, [])
I found that I had to rewrite all of my animated components to use useSharedValue instead of useState
@Andarius this does work, thanks. A bit convoluted.
I simplified it to the following, which still seemed to work
function callback(isCancelled: boolean){
'worklet'
runOnJS(setValue)(true);
}
React.useEffect(() => {
shared.value = someAnimation(callback)
}, [])
even further simplified to
React.useEffect(() => {
shared.value = someAnimation(() => {
'worklet';
runOnJS(setValue)(true)
});
}, [])
I'll need to do some further digging to understand when and where to use worklet.
Once again, thanks for the help!
@Andarius this does work, thanks. A bit convoluted.
I simplified it to the following, which still seemed to work
function callback(isCancelled: boolean){ 'worklet' runOnJS(setValue)(true); } React.useEffect(() => { shared.value = someAnimation(callback) }, [])even further simplified to
React.useEffect(() => { shared.value = someAnimation(() => { 'worklet'; runOnJS(setValue)(true) }); }, [])I'll need to do some further digging to understand when and where to use worklet.
Once again, thanks for the help!
This doesn't work either!
Most helpful comment
The following works