Estoy desarrollando una aplicación que tiene que obtener nuevos pedidos de la base de datos de Firestore. Usé el componentDidMount para actualizar la pantalla cada 10 segundos e iniciar la función fetchNewOrders . Si hay nuevos pedidos disponibles, la función debería insertar ese objeto en la matriz de estado newOrder y mostrar los pedidos en FlatList a continuación. Cuando inicio el código, devuelve el error TypeError: undefined is not an object (evaluating 'item.id') , también escribí el ejemplo de una matriz que estoy obteniendo de la base de datos.
Pantalla
export default class Received extends Component { constructor(props) { super(props); this.state = { loaded: false, newOrder: [], }; } async componentDidMount() { this.updateTimer = setInterval(() => { this.fetchNewOrders(); }, 10000); } fetchNewOrders = async () => { const querySnapshot = await getDocs(collection(db, path)); if(querySnapshot.length !== 0) { querySnapshot.forEach((doc) => { let array = this.state.newOrder; const data = doc.data().order; data.map(({obj, id}) => { const filter = array.find(c => c.id === id); if (filter == undefined) { array.push(obj) this.setState({ newOrder: array }) } }) }) } } render() { return ( <View> <FlatList data={this.state.newOrder} keyExtractor={item => item.id} renderItem={({ item }) => { return ( <TouchableOpacity> <Text>{item.serviceRequested}</Text> <View> <Tex>${item.total}</Text> </View> </TouchableOpacity> ) }} /> </View> ) } }datos (nuevo pedido)
Array [ Object { "date": "Mon Feb 28 2022 11:24:14 GMT-0500 (EST)", "id": 0.9436716663143794, "instructions": "", "order": Array [ ///////////// ], "paymentType": "Cash", "serviceRequested": "Delivery", "total": 10.4, }, ]Sugeriría filtrar sus datos (this.state.newOrder) primero. Esto haría que solo muestre los elementos que tienen identificadores.
Cambio sugerido:
<FlatList data={this.state.newOrder.filter((order)=>order.id)} keyExtractor={item => item.id} renderItem={({ item }) => { return ( <TouchableOpacity> <Text>{item.serviceRequested}</Text> <View> <Tex>${item.total}</Text> </View> </TouchableOpacity> ) }} />Arriba hay un código para solucionar este problema como se describe, pero le sugiero que se asegure de que Firestore solo envíe datos que tengan identificaciones si es posible. Obviamente, esto puede estar fuera de sus manos, pero me aseguraría de que Firestore le brinde datos confiables, ya que podría causar más problemas en el futuro.
setState es una función asíncrona que programa un procesamiento con un nuevo estado. Solo debe llamarse una vez por renderizado, no en un bucle.
const append = []; querySnapshot.forEach((doc) => { const data = doc.data().order; // Is there bad data without ids? data.filter(c => c.id && !this.state.newOrder.some(no => no.id === c.id)) .forEach((d) => append.push(d)); }); // Create the new state, then set it once. this.setState({ newOrder: [...this.state.newOrder, ...append]});