Home > Mobile >  React Native TextInput sends input on second press
React Native TextInput sends input on second press

Time:05-31

Guys i'm new to React Native and also not good at JavaScript. In my app i have 2 TextInput and a Pressable button but the output is not making sense. I've tried to change timing of execution of some lines but result is the same.

I'm using: expo, react native 0.68.2, android api 30 (Android Studio)

output:

Android Bundling complete 32ms

First click

LOG description :

LOG identity :

Second click

LOG description :sadasdas

LOG identity :12345678910


Report.js

export default function Report({ route, navigation }) {
  const [enteredText, setEnteredText] = useState("");
  const [enteredId, setEnteredId] = useState("");

  const [description, setDescription] = useState("");
  const [identity, setIdentity] = useState("");

  function descriptionInputHandler(enteredText) {
    setEnteredText(enteredText);
    //console.log("entered text :"   enteredText);
  }

  function identityInputHandler(enteredId) {
    setEnteredId(enteredId);
    //console.log("entered id :"   enteredId);
  }

  function buttonHandler() {
    setDescription(enteredText);
    setIdentity(enteredId);
    setEnteredText("");
    setEnteredId("");
    console.log("description :"   description);
    console.log("identity :"   identity);
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>{category}</Text>
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.longTextInput}
          placeholder="Describe your situation, don't worry we are here."
          onChangeText={descriptionInputHandler}
          value={enteredText}
        />
        <TextInput
          style={styles.textInput}
          placeholder="What is your identity number."
          onChangeText={identityInputHandler}
          value={enteredId}
        />
        <Pressable style={styles.button} onPress={buttonHandler}>
          <Text style={styles.text}>Send report!</Text>
        </Pressable>
      </View>
    </View>
  );
}

CodePudding user response:

Try something like that instead :

     function buttonHandler() {
    setDescription(enteredText);
    setIdentity(enteredId);
  }

 useEffect(() => {
    console.log("description :"   description);
    console.log("identity :"   identity);
    setEnteredText("");
    setEnteredId("");
    }, [description, identity]);

The useEffect should be triggered twice since both description and identity are in the dependency array but it's a good start to manage the asynchronous behavior of useState.

CodePudding user response:

Mutating the state isn't guaranteed to be synchronous (and most often, it is not). So right after using setDescription, you can't be sure that description will have the very last value.

Learn more about useState.

CodePudding user response:

First of all, provide only the code that is needed to solve your problem. About the problem: It is happening, because you re-render component with setDescription, setIdentity, setEnteredText and setEnteredId in buttonHandler(). And the value of description is not set immediately. As a workaround you can do something like:

function buttonHandler() {
    console.log("description :"   enteredText);
    console.log("identity :"   enteredId);

    setEnteredText("");
    setEnteredId("");
}

There is no need to use more variables.

  • Related