Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextInput loses focus after every keystroke react-native

Tags:

react-native

I have the following code (full example):

import React, { useState, useEffect } from 'react';
import { SafeAreaView, View, TextInput, Button, StyleSheet } from 'react-native';

const App = () => {
  const [textblocks, setTextblocks] = useState([]);
  const CreateTextBlockHandler = () => {
    let array = [...textblocks];
    array.push({text: ''});
    setTextblocks(array);
  };
  const SaveTextHandler = (index, text) => {
    let array = [...textblocks];
    array[index].text = text;
    setTextblocks(array);
  };
  const RenderTextInputs = () => {
      return textblocks.map((item, index) => {
        return (
          <View key={index}>
            <TextInput style={styles.textinput} placeholder="text" value={textblocks[index].text} onChangeText={value => SaveTextHandler(index, value)} />
          </View>
        );
      });
  };
  return (
    <SafeAreaView style={styles.pancontainer}>
      <RenderTextInputs />
      <Button title="Create textblock" onPress={CreateTextBlockHandler} />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  pancontainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  textinput: {
    width: 200,
    margin: 10,
    borderWidth: 1,
    borderColor: 'black'
  }
});

export default App;

How it works: I have a button to dynamically add a new textinput. This works. The problem is, for every character I enter in a textput, the focus is lost after every character.

I created a snack, you can test it here: https://snack.expo.io/BJcHxluyI.

I THINK I need to save the reference to the textinput somewhere, and then give the focus back to the textinput after every keystroke, but I don't know how to do that.

like image 432
Sam Leurs Avatar asked Jan 01 '23 09:01

Sam Leurs


1 Answers

Change

return (
    <SafeAreaView style={styles.pancontainer}>
      <RenderTextInputs />
      <Button title="Create textblock" onPress={CreateTextBlockHandler} />
    </SafeAreaView>
  );

To

return (
    <SafeAreaView style={styles.pancontainer}>
      {RenderTextInputs()}
      <Button title="Create textblock" onPress={CreateTextBlockHandler} />
    </SafeAreaView>
  );

Or put RenderTextInputs outside App and pass data via props. With first syntax react treats RenderTextInputs as a component and, as it is nested in App, mounts it again on each App render.

like image 141
Alexander Vidaurre Arroyo Avatar answered Mar 15 '23 22:03

Alexander Vidaurre Arroyo