1

From the sample code below i am trying to render textbox along with content inside Flatlist renderItem method and simultaneously trying to update textbox value.

Bad luck is on device after typing a single character, keyboard goes down.

Please find relevant Snack expo at : https://snack.expo.io/BJGMscqsS Here is code :

import * as React from "react";
import {
  View,
  Text,
  FlatList,

  TextInput
} from "react-native";

export default class App extends React.Component {
  state = {
data: []
  };
  updateItem = async (index, innerindex, itemAttributeVal) => {
    console.log(index, innerindex, itemAttributeVal);
    console.log(this.state.data);
    let { data } = this.state;
    data[index][innerindex].Value = itemAttributeVal;
    this.setState({
      data
    });
    console.log("newtry", this.state.data);
  };
  componentDidMount = async () => {
const listdata = 
  {
    totalRow: "2",
    coddindata: [
      {
        "SNo": "1",
        "Item": "10",
        "Material Code": "SERVICE LABOUR1",
        "Invoice Description": "Labour for Services1",
        "Invoice Item Amt": "765000.00",
        "Approved Quantity": "85",
      },
      {
        "SNo": "2",
        "Item": "20",
        "Material Code": "SERVICE LABOUR1",
        "Invoice Description": "Labour for Services2",
        "Invoice Item Amt": "810000.00",
        "Approved Quantity": "90",
      }
    ]
  }
;
const codingData = listdata.coddindata;
var finalarr = [];
var finalarr1 = [];
codingData.map(datavalue => {
  finalarr1 = [];
  Object.keys(datavalue).map((key, val) => {
    finalarr1.push({ Key: key, Value: datavalue[key] });
  });
  finalarr.push(finalarr1);
});
this.setState({
  data: [...this.state.data, ...finalarr],
  totalCount: listdata.totalRow
});
console.log(this.state.data);
  };

  render() {
return (
  <View style={{ flex: 1,padding: 20}}>
    <FlatList
      style={{ padding: 20 }}
      data={this.state.data}
      renderItem={({ item, index }) =>
        item.map((element, innerindex) => {
          // console.log(" innerindex  ",innerindex);
          const inputstateval = this.state.data[index][innerindex].Value;
          return (
            <View
              key={Math.random().toString()}
              style={{
                alignItems: "center",
                height: 30,
                justifyContent: "center",
                flexDirection: "row",
                lineHeight: 4
              }}
            >
              <View style={{ flex: 1, alignSelf: "stretch" }}>
                <Text>{element.Key}</Text>
              </View>
              {/* { element.Key != "total_amount" ? */}
              {element.Key !== "Approved Quantity" ? (
                <View
                  style={{ flex: 2, alignSelf: "stretch", marginTop: 3 }}
                >
                  <Text>{element.Value}</Text>
                </View>
              ) : (
                <View
                  style={{ flex: 2, alignSelf: "stretch", marginTop: 3 }}
                >
                  <TextInput
                    // defaultValue={element.Value}
                    placeholder={element.Key}
                    onChangeText={text => {
                      console.log("in onChangeText--- ");
                      this.updateItem(index, innerindex, text);
                    }}
                    value={this.state.data[index][innerindex].Value}
                    style={{
                      paddingTop: 1,
                      fontSize: 16,
                      borderWidth: 1,
                      height: 30,
                      marginTop: -6
                    }}
                  />
                </View>
              )}
            </View>
          );
        })
      }
      keyExtractor={item => Math.random().toString()}
    />
  </View>
);
  }
}
Mayur Baldha
  • 126
  • 1
  • 15

1 Answers1

1

In your code, you just need to fix the lines 87, and 132 to something like this:

87: key={'key'}
132: keyExtractor={(item) => ''+item}

So react knows that even after render, those text inputs are the same as the ones before the setState update.

Still, I cant manage to fix this same bug in my project.

  • While that may be good advise, if you're not able to answer the question you shouldn't post it as an answer. In the future, once you've earned more reputation around Stack Overflow, you'll have the opportunity to point out errors which are incidental to the main question as comments, which is more appropriate. – Jeremy Caney May 28 '20 at 19:07
  • @JeremyCaney, thanks for the advice, but the actual answer or cause of that bug is as I explained in the part: "So react knows that even after render, those text inputs are the same as the ones before the setState update." After the component re-renders the reference needs to be found again, otherwise it is considered a new component and the keyboard hides because the focus was on a component that no loger "exists" unless you explicitly say that is kept by conserving they same key. This is no doubt an answer. – Victor Esquivel May 28 '20 at 22:29