react-nativeexpo

update an object text value in textInput


The project is React Native with Expo. I have this code. I am looking for a way to edit or update the text value but have not found a solution.


import * as React from 'react';
import { StyleSheet, View, Image, TouchableOpacity, Text, Dimension, FlatList, SafeAreaView, TextInput, Dimensions,} from 'react-native';
import {useState} from 'react'

const data = [
  {
    name: "Home content",
    text: "This is my homepage. Here I welcome you to my website",
    status: "Home"
  },
  {
     name: "About content",
    text: "Here I go into details about myself and my business",
    status: "About"
  },
  {
     name: "Contact content",
    text: "Here we give you information on how to contact us ",
    status: "Contact"
  }
]

const listTab = [
  {
    status: 'Home'    
  },
  {
    status: 'About'    
  },
  {
    status: 'Contact'    
  },
]

export default function App() {

const [status, setStatus] = useState('Home')
const [dataList, setDataList] = useState([...data.filter(e => e.status === 'Home')])  
const [newText, setNewText ] = useState('');

const setStatusFilter = status => {
      if(status !== 'Home') {
        setDataList([...data.filter(e => e.status === status)])
      }else {
        setDataList([...data.filter(e => e.status === 'Home')])
      }

      setStatus(status)
    }

const renderItem = ({item, index}) => {
      return (
        <View key={index} style={styles.itemContainer}>                    
          <Text style = {styles.itemName}>{item.name}</Text>                     
          <TextInput
                      style = {styles.itemText}
                      mode="outlined"
                      multiline
                      value={item.text}
                      placeholder='FOR TEST' 
              placeholderTextColor={'gray'} 
                      onChangeText={(text) => setNewText(text)}
                    />
        </View>       
      )
 }

return (
      <SafeAreaView style={styles.container}>
        <View style={styles.listTab}>
          {
            listTab.map((e) => {
              return (
                <TouchableOpacity 
                  style={[styles.btnTab, status === e.status && styles.btnTabActive]}
                  onPress={() => setStatusFilter(e.status)}
                >
                  <Text style={styles.textTab, status === e.status && styles.textTabActive}>{e.status}</Text>
                </TouchableOpacity>
              )
            })
          }          
        </View>    

        <FlatList
          data={dataList}
          keyExtractor={(e,i) => i.toString()}
          renderItem={renderItem}
        />    
      </SafeAreaView>
    );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,        
    flexDirection: 'row',
    paddingHorizontal: 10,
    justifyContent: 'center'  
  },
  listTab: {
    backgroundColor: '#fff',    
    flexDirection: 'column',
    justifyContent: 'flex-start',
    marginTop: 20,    
    marginLeft: 5,    
    height: 100
  },
  btnTab: {
    width: 50,
    flexDirection: 'row',
    marginBottom: 10,
    paddingHorizontal: 15,
    paddingVertical: 10,
    justifyContent: 'center'
  },
   textTab: {
    fontSize: 16    
  },
  btnTabActive: {
    backgroundColor: 'purple',
    borderRadius: 5
  },
  textTabActive: {
    color: '#fff'
  },
  itemContainer: {    
    justifyContent: 'flex-end',
    paddingVertical: 15,
    marginLeft: 30,
    marginTop: 10
  },
  itemName: {
    fontWeight: 'bold',
    fontSize: 20,
    marginBottom: 5
  },
});




I want to modify the text value (onChangeText), but anything I enter in the textInput returns the item.text, could you please provide a solution for the text value issue?

Thanks in advance.

I tried numerous options but had no results until now.


Solution

  • To change the text value of the items dynamically in the TextInput, you need to update the dataList or the original data state when the text is modified. Here’s how you can modify your code.

    import React from 'react';
    import { StyleSheet, View, Image, TouchableOpacity, Text, Dimension, FlatList, 
    SafeAreaView, TextInput, Dimensions, } from 'react-native';
    import { useState } from 'react'
    
    const data = [
    {
    name: "Home content",
    text: "This is my homepage. Here I welcome you to my website",
    status: "Home"
    },
    {
    name: "About content",
    text: "Here I go into details about myself and my business",
    status: "About"
    },
    {
    name: "Contact content",
    text: "Here we give you information on how to contact us ",
    status: "Contact"
    }
    ]
    
    const listTab = [
    {
    status: 'Home'
    },
    {
    status: 'About'
    },
    {
    status: 'Contact'
    },
    ]
    
    export default function App() {
    
    const [status, setStatus] = useState('Home')
    const [dataList, setDataList] = useState([...data.filter(e => e.status === 
    'Home')])
    
    const setStatusFilter = status => {
    if (status !== 'Home') {
    setDataList([...data.filter(e => e.status === status)])
    } else {
    setDataList([...data.filter(e => e.status === 'Home')])
    }
    setStatus(status)
    }
    
    const handleTextChange = (text, itemIndex) => {
    const updatedList = [...dataList];    // Create a copy of the dataList
    updatedList[itemIndex].text = text;  //Update the text property of the item
    setDataList(updatedList);             // Set the updated dataList
    };
    const renderItem = ({ item, index }) => {
    return (
    <View key={index} style={styles.itemContainer}>
    <Text style={styles.itemName}>{item.name}</Text>
    <TextInput
    style={{ width: "90%", backgroundColor: "#CCCCCC", borderRadius: 10, height: 
    "auto", padding: 10 }}
    mode="outlined"
    multiline
    editable
    value={item.text}
    placeholder='FOR TEST'
    placeholderTextColor={'gray'}
    onChangeText={(text) => handleTextChange(text, index)}
    />
    </View>
    )
    }
    
    return (
    <SafeAreaView style={styles.container}>
    <View style={styles.listTab}>
    {
    listTab.map((e) => {
    return (
    <TouchableOpacity
    style={[styles.btnTab, status === e.status && styles.btnTabActive]}
    onPress={() => setStatusFilter(e.status)}>
    <Text style={styles.textTab, status === e.status && styles.textTabActive}> 
    {e.status}</Text>
    </TouchableOpacity>
    )
    })
    }
    </View>
    <FlatList
    data={dataList}
    extraData={dataList}
    keyExtractor={(e, i) => i.toString()}
    renderItem={renderItem}
    />
    </SafeAreaView>
    );
    }
    const styles = StyleSheet.create({
    container: {
    flex: 1,
    flexDirection: 'row',
    paddingHorizontal: 10,
    justifyContent: 'center'
    },
    listTab: {
    backgroundColor: '#fff',
    flexDirection: 'column',
    justifyContent: 'flex-start',
    marginTop: 20,
    marginLeft: 5,
    height: 100
    },
    btnTab: {
    width: 10,
    flexDirection: 'row',
    marginBottom: 10,
    paddingHorizontal: 15,
    paddingVertical: 10,
    justifyContent: 'center'
    },
    textTab: {
    fontSize: 16
    },
    btnTabActive: {
    backgroundColor: 'purple',
    borderRadius: 5
    },
    textTabActive: {
    color: '#ffffff'
    },
    itemContainer: {
    justifyContent: 'flex-end',
    paddingVertical: 15,
    marginLeft: 30,
    marginTop: 10
    },
    itemName: {
    fontWeight: 'bold',
    fontSize: 20,
    marginBottom: 5
    },
    });