Search code examples
reactjsreact-nativereact-native-flatlistuse-statereact-native-textinput

How can I change a specific string of an array of objects with TextInput in react native using react hook?


I have created a button that whenever is touched, it adds this object, {problema: '', solucion: '', key: Math.random(), index: index+1}, to this useState array, const [data, setData] = useState ([]). The constant data is used in a Flatlist that contains two TextInput, one for changing the string problema and the other to change the string solucion. My problem is that when you touch several times the button, the constant data will contain several object and I dont know how to change that specific string based on the TextInput that you use.

{
    
    let [index, setIndex] = useState(-1);

    let passingValue = { problema: '', solucion: '', key: Math.random().toString(), index: index+1  }

    const [data, setData] = useState([])

    const onPressPlus = () => {
        setIndex(index + 1)
        setData(prevState => [...prevState, passingValue])
        console.log(data);
    } 

    return (
       
        <View>

            <TouchableOpacity onPress={onPressPlus}>
                <AntDesign name='pluscircle'/>
            </TouchableOpacity>

            <View>
                <FlatList
                    data={data}
                    renderItem={itemData => (
                        <View style={{ flexDirection: 'row', }}>
                            <View> 
                                <TextInput
                                    placeholder="Escribe tu problema"
                                    placeholderTextColor='black'
                                    value={itemData.item.problema}
                                    onChangeText={(e) => { /* I dont know how to change the value of this specific itemData.item.problema with setData()*/ }}
                                    multiline={true}
                                    numberOfLines={2}
                                />
                            </View>
                            <View>
                                <TextInput
                                    placeholder="Escribe tu problema"
                                    placeholderTextColor='black'
                                    value={itemData.item.solucion}
                                    onChangeText={(e) => { /* I dont know how to change the value of this specific itemData.item.solucion with setData() */ }}
                                    multiline={true}
                                    numberOfLines={2}
                                />
                            </View>
                        </View>
                        )}
                    keyExtractor={itemData => itemData.key}
                />   
            </View>
        </View>
                    
    )
}

Solution

  • The straightforward solution is to pass the index of renderItem into the function, and write over the array

    onChangeText={str => setData(prev => {
                           prev[itemData.index] = { ...prev[itemData.index],solucion: str }
                           return prev
                           }
          }
    
    

    Anyhow, it seems like you want to have obj like data stored in array (with key value), consider treating your data as object, and render FlatList of Object.entries

    A better approach, and for not calling hugh setState on the whole list on each iteration, is to split renderItem into stand alone components, while question come as prop and answer is independent state, and when calling the onSubmit pass the inside values (what will require some state-managment architecture, form (can implementwith libary) or using local refs or context, if its just one time call from component to api)