maxi hraschan
maxi hraschan

Reputation: 300

TextInput in FlatList item gets unfocused when changing value of redux object

Im using a nested object which is safed in my redux store to render my FlatList. In each set item I got a textInput to change the reps in my set but every time I change the value of the input it gets unfocused and the keyboard dismisses. Is their a way to stop the input of getting unfocused?

I tried to insert the key property in the flatlist and also in my Item component but that didn`t help. Also tried to delete the extraData property of my FlatList. I guess in this case its not necessary to have this one.

Can anybody help ?

My object:

Workout:{
    ExercisList:[
        {
           sets to render:[
            {set 1 },
            {set 2},
            {set 3},
           ]
        },
        .
        .
        .
    ]
}

Flatlist:

<View>
<FlatList
      data={workout.exerciseList.find((exerciseList) => exerciseList.elid === route.params.elid)?.sets}
      renderItem={renderItem}
      extraData={workout.exerciseList.find((exerciseList) => exerciseList.elid === route.params.elid)?.sets}
      keyExtractor={(item) => item.sid.toString()}
/>
</View>

RenderItem:

const renderItem = ({ item }: { item: Set }) => {
    return (
        <Item
            key={item.sid}
            sid={item.sid}
            elid={item.elid}
            sortOrder={item.sortOrder}
            reps={item.reps}
            weightKG={item.weightKG}
            weightLBS={item.weightLBS}
            finished={item.finished}
        />
    );
};

Item:

    const Item = ({ sortOrder, reps, weightKG, weightLBS, sid, elid }: Set, key: any) => {
    return (
        <Swipeable
            rightThreshold={30}
            renderRightActions={() => (
                <View style={{ backgroundColor: "red" }}>
                    <Text>Delete</Text>
                </View>
            )}
            onSwipeableRightOpen={() => console.log("Delete Set")}
        >
            <View style={styles.item} key={key}>
                <Text>{sortOrder}</Text>
                <Text>{lang.t("reps")}</Text>
                <TextInput
                    key={sid}
                    onChangeText={(reps) => changeReps(reps, sid, elid)}
                    value={reps.toString()}
                    keyboardType='number-pad'
                ></TextInput>
                
            </View>
        </Swipeable>
    );
};

ChangeReps Here the workout object in my redux store gets changed.

const changeReps = (reps: string, sid: string, elid: string) => {
    dispatch(updateRepsWorkout(parseInt(reps), sid, elid));
};

Upvotes: 1

Views: 332

Answers (1)

maxi hraschan
maxi hraschan

Reputation: 300

Found following workaround:

I set a state in each item component for my reps. When OnChangeText gets triggered only the state updates. After that i update my redux store object only if the textInput loses focus with the "OnEndEdit" prop.

const Item = ({ sortOrder, reps, weightKG, weightLBS, sid, elid, finished, index }: any) => {
    const [outputReps, setOutputReps] = React.useState(reps.toString());

    return (
        <Swipeable
            rightThreshold={30}
            renderRightActions={() => (
                <View style={{ backgroundColor: "red" }}>
                    <Text>Delete</Text>
                </View>
            )}
            onSwipeableRightOpen={() => console.log("Delete Set")}
        >
            <View style={styles.item}>
                <Text>{sortOrder}</Text>
                <Text>{lang.t("reps")}</Text>
                <TextInput
                    key={sid}
                    onChangeText={(reps) => setOutputReps(reps)} <-- Here I change state!
                    onEndEditing={() => changeReps(outputReps, sid, elid)} <-- here I change my redux object 
                    value={outputReps}
                    keyboardType='number-pad'
                ></TextInput> 
            </View>
        </Swipeable>
    );
}

Upvotes: 1

Related Questions