Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

241
Visualizações
Cómo aislar correctamente los estados en React

Quiero que los elementos secundarios actualicen el estado de mi componente principal de forma independiente, sin que el elemento principal realice una microgestión y esté al tanto de las variables modificadas por sus elementos secundarios. Estoy resumiendo estas modificaciones con un solo método onIssueDataChanged . El objeto de state modificado luego se transferirá a GraphQL, por lo que no es necesario que el padre sepa lo que contiene. Mi problema es que los niños no pueden llamar a onIssueDataChanged en useEffect .

Aquí está el problema concreto:

Tengo un formulario IssueFieldsForm que maneja el guardado de un objeto llamado issue .

El objeto tiene una galería de imágenes incluida, las imágenes se pueden agregar, eliminar o seleccionar como la imagen principal del problema. Esa lógica está aislada en un componente separado llamado GalleryComp y la información se almacena en un campo de problema no persistente llamado attachmentsMeta .

Mi problema es que quiero aislar el manejo de los attachmentsMeta en GalleryComp y tener en IssueFieldsForm un método genérico al que llamé onIssueDataChanged que solo toma valores modificados y actualiza el estado de la variable de issue con él. Eso parece difícil de hacer ya que inicializo un estado de attachmentsMeta en GalleryComp con los attachments actuales en el useEffect , pero no puedo enviar eso de vuelta al objeto de estado de issue en el padre.

 export default function GalleryComp(props) { const {issue, onItemsChanged} = props const [attachmentsMeta, setAttachmentsMeta] = useState({ images: [], attachmentsAttributes: {}, mainAttachmentIndex: 0 }) useEffect(() => { const newAttachmentsMeta = {...attachmentsMeta} newAttachmentsMeta.images = [] logger.debug('attachments cont before concat: ', newAttachmentsMeta.images.length) newAttachmentsMeta.images = unionBy(issue.attachments, issue.attachmentsMeta?.images, 'url') logger.debug('after concat: ', newAttachmentsMeta.images.length) newAttachmentsMeta.mainAttachmentIndex = issue.mainAttachmentIndex logger.debug('displaying attachments: ', newAttachmentsMeta) setAttachmentsMeta(newAttachmentsMeta) }, [issue?.attachmentsMeta])

Eso es un problema para mí porque si no hago ningún cambio en los archivos adjuntos, nunca se llamará a onIssueDataChanged para actualizar la variable issue.attachmentsMeta con los attachments iniciales. Lo que me llevó a perder mis archivos adjuntos originales al guardarlos (ya que no se transfirieron a mi única fuente de verdad, problema. issue.attachmentsMeta ).

Por otro lado, si inicializo issue.attachmentsMeta en el componente principal, pierdo la elegancia de que cada componente maneje sus propias variables.

pd: Obviamente, no puedo llamar a onIssueDataChanged en el efecto, ya que desencadenaría un cambio de estado y entraría en un bucle infinito.

¿Cómo harías esto?

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Resolví el problema exportando una función initGalleryData de GalleryComp y usándola en el formulario. De esta manera, los detalles se ocultan en el niño.

De esta manera, puedo reutilizar el Componente de la Galería con cualquier objeto, simplemente sin olvidar iniciar el objeto y proporcionando un modificador 'onDataChange'

Este código se usa en el proyecto weally.org , que reúne a personas para protestas en línea por concens

 export default function GalleryComp(props) { const {issue, onItemsChanged} = props const attachmentsMeta = issue.attachmentsMeta const {t} = useTranslation('complaintList') function setMainAttachmentIndex(index) { const attachmentsMetaCopy = {...attachmentsMeta} attachmentsMetaCopy.mainAttachmentIndex = index onItemsChanged({attachmentsMeta:attachmentsMetaCopy}) } function onAttachmentRemoveAction(attachmentId, removed) { const attachmentsModified = {...attachmentsMeta} let attr = attachmentsModified.attachmentsAttributes[attachmentId] if (!attr) { attr = {deleted: removed} attachmentsModified.attachmentsAttributes[attachmentId] = attr } else { attr.deleted = removed } onItemsChanged({attachmentsMeta: attachmentsModified}) } if (attachmentsMeta.images?.length === 0) return <Divider style={sx.descDivider}/> return ( <> <Gallery attachments={attachmentsMeta} onRemoveAction={onAttachmentRemoveAction} selectedIndex={attachmentsMeta.mainAttachmentIndex} onSelectionChange={setMainAttachmentIndex}/> <Divider style={sx.descDivider}/> </> ) } export function initGalleryData(issue) { issue.attachmentsMeta = { images: [...issue.attachments], attachmentsAttributes: {}, mainAttachmentIndex: 0 } }

Luego solo tengo que inicializar los campos necesarios en la creación del componente.

 export default function IssueFieldsForm(props) { const {t} = useTranslation('complaintList') const { issue, onIssueDataChanged, markers, onMarkersChanged, onMarkerSelected, setPlaceMarkersDisplayed, placeMarkersDisplayed } = props initGalleryData(issue); const [validationState, setValidationState] = useState(new ValidationResult()) //... return ( <Card sx={sx.issueFieldsForm} id="IssueFieldsForm"> <Grid item sx={sx.item} ref={scrollTopRef}> <Typography variant={'h5'} sx={sx.header}>{t('edit.header')}</Typography> </Grid> //... <GalleryComp issue={issue} onItemsChanged={onIssueDataChanged}/> //... )
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda