I have a TextInput in my React native project. I use an onCHangeText={(text)=>handleChange(‘postText’, text)} function to update the formData that I had set as a State Object at the beginning of the function. The result I get is whenever I type, the app restarts and refreshes, deleting former content and only writing the latest character to the text field. Worse, it hides the keypad altogether.
Here is my code:
const HomePageBuilder = ({navigation}) =>{
const [postingMedia, setPostingMedia] = useState(null);
const [selectedValue, setSelectedValue] = useState(null);
const [images, setImages] = useState([]);
const screenWidth = Dimensions.get('window').width;
const {userId, login, logout, user} = useContext(AppContext);
const [postData, setPostData] = useState({postMedia : '',
postText : '', postType : 'General'
});
const handleChange = (fieldName, value)=>{
setFormData(prevState =>({
...prevState,
[fieldName]:value
}));
}
return(<>
<Header />
<SafeAreaView style = {HomeStyles.container}>
<View style = {HomeStyles.bodyMain}>
<>
<FlatList
data = {posts}
renderItem={postBuilder}
keyExtractor={(item, index) => index.toString()}
style ={{marginBottom: 20, paddingBottom: 20}}
ListHeaderComponent={()=>(
<View style = {HomeStyles.postMakerDiv}>
<View>
<TextInput placeholder="Share some news" style = {HomeStyles.postBoxMain}
ref = {postInputRef}
// onChangeText={(text) => handleChange('postText', text)}
value = {postData.postText}
onEndEditing={(text) => setPostText(text)}
/>
</View>
<View style = {HomeStyles.imageBox}>
{images.length > 0 && (
<>
<Pressable style = {{zIndex: 1}} onPress = {()=>{
setImages([]);
}}>
<Image source = {require("../../views/resources/close-circle.png")} style = {{width: 25, height: 25, left: '96%', top: 15, zIndex: 1}}/>
</Pressable>
<ScrollView horizontal style={{ marginTop: 20, height: 320}} contentContainerStyle = {HomeStyles.picturesPreview}>
{images.map((imageUri, index) => (
<View key={index} style={{ margin: 5 }}>
<Image
source={{ uri: imageUri }}
style={{ minWidth: screenWidth * 0.9, maxWidth: screenWidth * 0.9, height: 300, borderRadius: 10 }}
/>
</View>
))}
</ScrollView>
</>
)}
</View>
<View style = {HomeStyles.imageBox}>
{
videoUri ?(
<>
<Pressable onPress = {()=>{
setVideoUri(null);
}} style = {{width: 30, height: 30, flexDirection: 'row', alignSelf: 'flex-end'}}>
<Image source = {require("../../views/resources/close-circle.png")} style = {{width: 25, height: 25, zIndex: 1, top: 10}}/>
</Pressable>
<TouchableOpacity onPress = {togglePlayback}>
<Video
source = {{uri: videoUri}}
resizeMode = "cover"
style = {{width: '100%', height: 400, borderWidth: 1, borderRadius: 30}}
ref = {videoRef}
shouldPlay = {isPlaying}
isLooping
/>
</TouchableOpacity>
</>
):(
<>
</>
)
}
</View>
<View style = {HomeStyles.postOptions}>
<Picker
selectedValue={postData.postType}
style={{ height: 50, minWidth: 130, borderWidth: 1, borderColor: 'grey' }}
onValueChange={(text) => handleChange('postType', text)}
>
<Picker.Item label="General" value="General" />
<Picker.Item label="Business" value="Business" />
<Picker.Item label="Politics" value="Politics" />
<Picker.Item label="Lifestyle" value="Lifestyle" />
<Picker.Item label="Relationship" value="Relationship" />
<Picker.Item label="Music" value="Music" />
<Picker.Item label="Art" value="Art" />
<Picker.Item label="Entertainment" value="Entertainment" />
</Picker>
<TouchableOpacity onPress={pickImages}>
{/* Modify this to call the multiple images function later.*/}
<Icon name="camera-alt" size={25} color="purple" style = {{top: 10}}/>
</TouchableOpacity>
<TouchableOpacity onPress = {chooseVideo}>
<Icon name="videocam" size={25} color="purple" style = {{top: 10}}/>
</TouchableOpacity>
<TouchableOpacity style = {HomeStyles.postBtnMain} onPress = {makePost}>
<Text style = {{color: 'white', fontWeight: 'bold', fontSize: 15}}>
Share
</Text>
{/* <Icon name="campaign" size={25} color="white" style = {{top: -2}}/> */}
</TouchableOpacity>
</View>
</View>
)}
ListEmptyComponent={()=>(
<View style = {{justifySelf : 'center', alignSelf : 'center', justifyContent : 'center', alignContent: 'center', width: 300, marginTop: 50}}>
<Text style = {{fontSize: 20, color: 'grey', textAlign: 'center'}}>
Seems you are having some internet issues.
</Text>
<TouchableOpacity onPress = {()=> navigation.navigate("Home")} style = {{backgroundColor: 'purple', justifyContent : 'center', alignContent: 'center', padding: 10, borderRadius: 10, marginTop: 30}}>
<Text style = {{textAlign: 'center', color: 'white'}}>
Try again?
</Text>
</TouchableOpacity>
</View>
)}
/>
</>
</View>
</SafeAreaView>
</>
);
The element causing this is styled with styles.postBoxMain
I have tried Isolating this TextINput by giving it it’s own state separate from the postData object. I have tried using useRef.current.value. I have tried using lodash’s debounce, none of these techniques seem to be working.
I just need the textinput field to act normally and be stored in the postData.postText object. This is not working out. I have even tried onEndEditing. Everything I have done just reflects the same error.