skip to Main Content

I have something like :

onChangeText={(value) => setValue(value)}

important value is a global state because I need according to one condition to modify the value by another from an API call, the really unexpected problem arises when it comes to a long chain for example :

"In the Shadow of Young Girls in Flowers, published in 1913, second volume of In Search of Lost Time, won the Goncourt Prize in 1919. For Marcel Proust (1871-1922), it was the rebirth of a work"

onChangeText={(value) => { setValue(value) console.log('onChangeText value')

I observe 5 logs with a different translation :

"In the SIn the Shadow of Young Girls in Flowers, published in 1913, second volume of In Search of Lost Time, won the Goncourt Prize in 1919. For Marcel Proust (1871-1922), it was the rebirth of a work"

how is it possible for react to modify my value?

2

Answers


  1. Chosen as BEST ANSWER

    Thank you for your reply,

    This morning while doing tests, I realized that it is the combination of multiline={true} and maxLength={200} which causes this bug, I will let you see this (you have to put yourself on IOS) : demo


  2. Waiting for the api response could make the keyboard seem slow and since the user will still be able to type, when the api result finally was updated in state it would give you weird behavior. I think it would be better if you decoupled the global state from the textinput and only update it after the api call (demo):

    import { Text, SafeAreaView, StyleSheet, View } from 'react-native';
    import { Card, TextInput } from 'react-native-paper';
    import { useState, useCallback, useMemo } from 'react';
    import useFetchData from './useFetchData';
    import stringSimilarity from 'string-similarity';
    
    // simulate your use case of updating the text input with data
    const initialString = 'An aple mobile which is nothing like aple';
    // then we set the string to the closest matching product description
    const getBestMatch = (str, list) => {
      return stringSimilarity.findBestMatch(
        str,
        list.map((l) => l.description)
      ).bestMatch.target;
    };
    
    export default function App() {
      const [list, listLoading, listError] = useFetchData();
      const [description1, setDescription1] = useState(initialString);
      const [description2, setDescription2] = useState(initialString);
      // storing the description separately from the textinput
      const apiDescription = useMemo(() => {
        if (list.length > 0 && description2.length)
          return getBestMatch(description2, list);
        return '';
      }, [description2, list]);
      return (
        <SafeAreaView style={styles.container}>
          <View style={styles.input}>
            <Text>
              After typing the first character this textinput becomes hard to use
            </Text>
            <TextInput
              placeholder="Weirdness"
              value={description1}
              onChangeText={(text) => {
                const bestMatch = getBestMatch(text, list);
                console.log(bestMatch);
                setDescription1(bestMatch || text);
              }}
            />
          </View>
          <View style={styles.input}>
            <Text>This text input remains usable</Text>
            <TextInput
              placeholder="Some text"
              value={description2}
              onChangeText={setDescription2}
            />
            <Text>
              Updated text:{'n'}
              {apiDescription}
            </Text>
          </View>
        </SafeAreaView>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
      input: {
        marginBottom: 20,
        padding: 10,
      },
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search