wcandillon / react-native-redash

The React Native Reanimated and Gesture Handler Toolbelt
https://wcandillon.gitbook.io/redash/
MIT License
1.99k stars 117 forks source link

<ReText /> Not updating UI for Web #453

Closed Squair closed 3 years ago

Squair commented 3 years ago

Hey, I spent a bit of time earlier today trying to get ReText to work on web and can't seem to figure out if I'm just using incorrectly or there's a bit more to it. I couldn't find anything explicit in the docs saying that this is available for web, although seeing that react-native-reanimated 2.0.0 should support web, I thought it might...

expo: 41.0.1 react: 16.13.1 react-native: 0.63 react-native-redash: 16.0.11 react-native-reanimated: 2.1.0 react-native-web: 0.13.12

Heres a bit of boilerplate to re-create:

import React from 'react';
import { Button, View } from 'react-native';
import { useDerivedValue, useSharedValue } from 'react-native-reanimated';
import { ReText } from 'react-native-redash';

const Test = () => {
  let foo = useSharedValue(0);
  const count = useDerivedValue(() => { return foo.value.toString() });

  const incrementCounter = () => {
    foo.value++;
    console.log(foo.value);
  }

  return (
    <View>
          <ReText text={count} />
          <Button title={"Counter"} onPress={incrementCounter}/>
    </View>
  );
}

export default Test;

Behaviour on Android: works as expected, counter increments on press.

Behaviour on Web: Count doesn't update on the ui, although the state is still mutated and logged to the console. image

wcandillon commented 3 years ago

Since we use a TextInput on React Native to animated text, could you make a fallback .web.tsx to animated text on web?

Squair commented 3 years ago

A fallback to provide an alternative specifically to a TextInput?

My only confusion with that is that a TextInput will still render correctly on web with the initial state from the shared value, which leads me to believe it should be possible to update without adding platform specific code.

Otherwise is there something I've missed about a TextInput in the context of web that's means this isn't possible out of the box?

nandorojo commented 3 years ago

@Squair ReText on native uses the text prop. I think we need to change the prop to value to get this to work on Web.

This line probably needs to change to something like this to work on Web:

const animatedProps = useAnimatedProps(() => {
  return Platform.select({
    default: { value: text.value },
    native: {
      text: text.value
      // Here we use any because the text prop is not available in the type
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } as any
  })
})

However, I'm not sure if that will work. We may need to use Text on Web. I'll investigate and can PR.

nandorojo commented 3 years ago

Looks like on Web, the value prop in useAnimatedProps works on the first render, but not after that.

Video: https://www.loom.com/share/15c847e8de224c569cd4ee56784dc941

Repro: https://snack.expo.dev/@nandorojo/ranting-cheese

Seems like a Reanimated issue, I'll follow up there.

nandorojo commented 3 years ago

In case you need a hack, the snack I linked to above does solve it, using setNativeProps.

nandorojo commented 3 years ago

A web-compatible ReText component can be found here: https://github.com/coinjar/react-native-wagmi-charts/blob/master/src/components/AnimatedText.tsx