这是我的情况:我有一个带有一些状态的组件。其中一个(documents
)用于存储组件列表的数据,因此状态是一个对象数组。
按钮向 API 发出请求,该请求会删除系统上的某个组件。在请求之后,我想从状态中删除这个元素。我已经使用过滤器实现了这个(函数 removeDocument
),该过滤器返回一个在 setDocuments
中用作参数的数组。开发这个我注意到状态 documents
是空的。 如果我没有在任何地方调用 setDocuments
,为什么会发生这种情况?
import React, { useState, useEffect, useContext } from "react";
import { KeyboardAvoidingView, View, Image, Text, InteractionManager, ActivityIndicator, TouchableOpacity } from "react-native";
import styles from './style';
import mainStyles from '../../style';
import UserInfo from '../../../../config/context';
import { AcademicCapOutline, BanOutline, BriefcaseOutline, CalendarOutline, CashOutline, CheckCircleOutline, DocumentDuplicateOutline, EyeOutline, FingerPrintOutline, FlagOutline, HeartOutline, Home, HomeOutline, IdentificationOutline, InboxIn, InboxInOutline, LinkOutline, MailOutline, MapOutline, OfficeBuildingOutline, PencilAlt, PhoneIncomingOutline, PhoneOutline, Trash, ViewGridAdd } from 'react-native-heroicons';
import ButtonsRow from '../../../components/buttons/row/buttonsRow';
import ListTitle from '../../../components/listTitle/listTitle';
import { ScrollView } from "react-native-gesture-handler";
import DocumentList from '../../../components/documents/documentList';
import DataList from '../../../components/list/dataList/dataList';
import { getUsers, getDocument, deleteDocument } from './api';
import Popup from '../../popup/popup';
import DocumentPopup from '../../popup/document/document';
import { useCallback } from "react";
const PersonScreen = (props) => {
const { user, refreshToken } = useContext(UserInfo);
const [buttons, setButtons] = useState([]);
const [documents, setDocuments] = useState([]);
const [data, setData] = useState([]);
const [name, setName] = useState('');
const [popup, setPopup] = useState({open: false});
useEffect(() => {
let b = [];
if(user.rol != 'I' && user.rol != 'P'){
if(user.rol == 'G')
b.push({key: '3', icon: ViewGridAdd, action: () => console.log('hola')});
if(user.rol == 'A')
b = b.concat([
{key: '1', icon: PencilAlt, action: () => console.log('hola')},
{key: '2', icon: Home, action: () => console.log('hola')},
{key: '3', icon: ViewGridAdd, action: () => console.log('hola')},
{key: '4', icon: InboxIn, action: () => console.log('hola')},
{key: '5', icon: Trash, action: () => console.log('hola')},
])
}
setButtons(b);
var interaction = InteractionManager.runAfterInteractions( () => {
getUsers(user, refreshToken, props.id)
.then(data => {
setName(data.nombre);
// Set Documents
if(data.documentos){
setDocuments(data.documentos.map( d => {
return { ruta: d.ruta, title: d.documento.nombre, size: d.documento.tamano, type: 'Document', onPress: () => { openDocument( d.ruta, d.documento.nombre ) } }
}))
}
// Set Data
let d = [];
if(data.activo != undefined)
d.push({ key: 'activo', icon: CheckCircleOutline, title:"Estado", data: ( data.activo ? 'Alta' : 'Baja' )})
if(data.email)
d.push({ key: 'email', icon: MailOutline, title:"Dirección de email", data: data.email})
if(data.documento_id)
d.push({ key: 'documento_id', icon: IdentificationOutline, title:"Documento de identificación", data:data.documento_id})
if(data.tipo_documento_id)
d.push({ key: 'tipo_documento_id', icon: IdentificationOutline, title:"Tipo de documento de identificación", data:data.tipo_documento_id})
if(data.fecha_nacimiento)
d.push({ key: 'fecha_nacimiento', icon: CalendarOutline, title:"Fecha de nacimiento", data:data.fecha_nacimiento})
if(data.genero)
d.push({ key: 'genero', icon: FingerPrintOutline, title:"Genero", data:data.genero})
if(data.direccion)
d.push({ key: 'direccion', icon: MapOutline, title:"Dirección", data:data.direccion})
if(data.ciudad)
d.push({ key: 'ciudad', icon: OfficeBuildingOutline, title:"Ciudad", data:data.ciudad})
if(data.pais)
d.push({ key: 'pais', icon: FlagOutline, title:"País", data:data.pais})
if(data.telefono)
d.push({ key: 'telefono', icon: PhoneOutline, title:"Teléfono", data:data.telefono})
if(data.pais_nacimiento)
d.push({ key: 'pais_nacimiento', icon: FlagOutline, title:"País de nacimiento", data:data.pais_nacimiento})
if(data.pais_procedencia)
d.push({ key: 'pais_procedencia', icon: FlagOutline, title:"País de procedencia", data:data.pais_procedencia})
if(data.estado_civil)
d.push({ key: 'estado_civil', icon: LinkOutline, title:"Estado civil", data:data.estado_civil})
if(data.formacion)
d.push({ key: 'formacion', icon: AcademicCapOutline, title:"Formación", data:data.formacion})
if(data.ocupacion)
d.push({ key: 'ocupacion', icon: BriefcaseOutline, title:"Ocupación", data:data.ocupacion})
if(data.permiso_trabajo != undefined)
d.push({ key: 'permiso_trabajo', icon: BanOutline, title:"Permiso de trabajo", data: ( data.ocupacion ? 'Sí' : 'No' )})
if(data.estado_documentacion)
d.push({ key: 'estado_documentacion', icon: BriefcaseOutline, title:"Estado de la documentación", data:data.estado_documentacion})
if(data.estado_empadronamiento)
d.push({ key: 'estado_empadronamiento', icon: DocumentDuplicateOutline, title:"Estado de empadronamiento", data:data.estado_empadronamiento})
if(data.tarjeta_sanitaria)
d.push({ key: 'tarjeta_sanitaria', icon: HeartOutline, title:"Estado de tarjeta sanitaria", data:data.tarjeta_sanitaria})
if(data.observaciones)
d.push({ key: 'observaciones', icon: EyeOutline, title:"Observaciones", data:data.observaciones})
if(data.cuota)
d.push({ key: 'cuota', icon: CashOutline, title:"Cuota", data: `${data.cuota} €`})
if(data.newsletter != undefined)
d.push({ key: 'newsletter', icon: InboxInOutline, title:"Quiere newsletter", data: ( data.newsletter ? 'Sí' : 'No' )})
if(data.disponibilidad_mananas != undefined)
d.push({ key: 'disponibilidad_mananas', icon: CalendarOutline, title:"Disponibilidad de mañanas", data: ( data.disponibilidad_mananas ? 'Sí' : 'No' )})
if(data.disponibilidad_tardes != undefined)
d.push({ key: 'disponibilidad_tardes', icon: CalendarOutline, title:"Disponibilidad de tardes", data: ( data.disponibilidad_tardes ? 'Sí' : 'No' )})
if(data.disponibilidad_fines_de_semana != undefined)
d.push({ key: 'disponibilidad_fines_de_semana', icon: CalendarOutline, title:"Disponibilidad en fin de semana", data: ( data.disponibilidad_fines_de_semana ? 'Sí' : 'No' )})
if(data.experiencia_previa)
d.push({ key: 'experiencia_previa', icon: EyeOutline, title:"Experiencia previa", data:data.experiencia_previa})
setData(d);
})
.catch( e => {
// Error
})
})
return InteractionManager.clearInteractionHandle(interaction);
}, [])
const openDocument = (ruta, nombre) => {
setPopup({
open: true,
component: DocumentPopup,
title: nombre,
componentProps: {
remove: () => { removeDocument(ruta) },
download: () => { downloadDocument(ruta) }
}
})
};
const closePopup = () => {
setPopup({open: false});
}
const removeDocument = (ruta) => {
deleteDocument(user, refreshToken, ruta)
.then( removed => {
console.log(documents) // <--- Array []
if( removed ){
setDocuments(documents.filter( d => { return d.ruta !== ruta } ));
}
closePopup();
})
.catch( e => {
// Error
console.log(e);
} )
}
const downloadDocument = (ruta) => {
getDocument(user, refreshToken, ruta);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={[mainStyles.screenContainer, styles.mainView]}
>
<View style={styles.topSection}>
<View style={styles.topInfo}>
<Image
style={styles.image}
source={require('../../../assets/default-person.png')}
/>
<View style={styles.nameView}>
<Text
style={styles.name}
numberOfLines={2}
ellipsizeMode={'tail'}
>{name}</Text>
<View style={styles.location}>
<HomeOutline
style={styles.homeIcon}
stroke={'#121212'}
/>
<Text style={styles.homeText}>Casa E | Habitación 3</Text>
</View>
</View>
</View>
<ButtonsRow
buttons={buttons}
/>
</View>
<View style={styles.bottomSection}>
<ScrollView style={styles.scroll} showsVerticalScrollIndicator={false}>
{ documents.length!=0 &&
<ListTitle title={'Documentos'} />
}
{ documents.length!=0 &&
<DocumentList
style={styles.documents}
documents={documents}
/>
}
{ data.length!=0 &&
<View style={styles.datos}>
<ListTitle title={'Datos'} />
<DataList data={data} />
</View>
}
{ documents.length==0 && data.length==0 &&
<ActivityIndicator style={styles.loading} size="large" color="#054956" />
}
</ScrollView>
</View>
{ popup.open && <TouchableOpacity activeOpacity={0.6} style={mainStyles.outsidePopup} onPress={closePopup} /> }
{ popup.open &&
<Popup
title={popup.title}
component={popup.component}
componentProps={popup.componentProps}
/>
}
</KeyboardAvoidingView>
);
}
module.exports = PersonScreen;
答案 0 :(得分:0)
我遵循了这个解决方案:
我不完全理解 React 在这种情况下是如何工作的,但我找到了一个使用 refs 的解决方案。我不知道为什么,但不修改状态,它并不总是最新的。为了确保我使用的是最后一个,我创建了一个指向 document
状态的最后一个版本的引用:
{...}
const [documents, setDocuments] = useState([]);
const [data, setData] = useState([]);
const [name, setName] = useState('');
const [popup, setPopup] = useState({open: false});
const docsRef = useRef();
docsRef.current = documents;
现在,我不再使用函数内部的文档,而是使用 docsRef.current
。