skip to Main Content

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.

2

Answers


  1. your setter is called setPostData but in your handleOnChange you have it as setFormData so it basically doesn’t exist and that’s why the app is breaking, just change the code inside handleOnChange as this:

    const handleChange = (fieldName, value)=>{
        setPostData(prevState =>({
            ...prevState,
            [fieldName]:value
        }));
    }
    
    Login or Signup to reply.
  2. Agree with the answer by @Eduardopalacio

    Adding to it:

    Please see the example code here Using a single event handler for multiple fields . It shows how to use eventObject.target.name and eventObject.target.value properties to write more concise code as shown below.

    function handleChange(e) {
        setPerson({
          ...person,
          [e.target.name]: e.target.value
        });
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search