Tengo una situación en la que en una pantalla (AScreen), cargo datos JSON desde un archivo .json, también tengo una pantalla de Configuración donde el usuario puede configurar 'settingA' como verdadero o falso.
AScreen (básicamente, si settingA se establece en verdadero, cargue dos archivos JSON, si settingA es falso, cargue solo un archivo de datos):
import React, { useContext } from 'react'; import { SettingsContext } from '../context/settingsContext'; const AScreen = () => { const { settingA } = useContext(SettingsContext); const loadedData = (() => { if (settingA === true) { console.log('True'); return Object.assign( require('../assets/data/jsonFileA.json'), require('../assets/data/jsonFileB.json') ) } console.log('False'); return require('../assets/data/jsonFileA.json') })(); console.log(settingA): console.log(loadedData); return ( ... ); };El problema aquí es que si cargo la aplicación y me dirijo a AScreen, obtengo los datos correctos cargados en loadedData. Sin embargo, si luego me dirijo a la página de configuración y cambio la configuración, luego vuelvo a AScreen, el archivo console.log (settingA) muestra la configuración actualizada y se imprime el 'Verdadero' o 'Falso' correcto, pero los datos cargados aún contienen los datos. desde la primera vez que visité AScreen.
Esto me dice que la función require() en realidad no se llama hasta que la pantalla se vuelve a renderizar por completo.
¿Hay una mejor manera de cargar datos JSON que require ()? ¿O cómo puedo asegurarme de que se llame a require() cada vez que se muestre la pantalla, incluso si la pantalla no se vuelve a renderizar?
Sé que una opción sería cargar todos los datos JSON y luego simplemente filtrarlos según la configuración del usuario, pero en la aplicación real hay muchos más archivos de datos, por lo que parece que sería una pérdida de recursos cargar todos los archivos a la vez. .
delete require.cache[require.resolve('../assets/data/jsonFileA.json')]; ...Independientemente de cuántas formas intenté configurar loadingData en {}, ejecutar el comando delete require.cache[] , usar let en lugar de const, etc. Siempre terminé igual con los datos cargados que no se actualizaban correctamente.
Resulta que el problema era de la función Object.assign() . En lugar de usar:
return Object.assign( require('../assets/data/jsonFileA.json'), require('../assets/data/jsonFileB.json') )Solía:
return Object.assign( {}, require('../assets/data/jsonFileA.json'), require('../assets/data/jsonFileB.json') ) donde {} básicamente anula el objetivo, que es 'loadedData' y lo restablece con los nuevos datos. Sin {}, las instrucciones require solo actualizaban la ubicación en la memoria donde la función require() originalmente colocó los datos, por lo tanto, no estaba obteniendo los cambios que estaba buscando.
Advertencia para cualquiera que necesite esto en el futuro: el método Object.assign() crea una copia superficial, por lo que si la fuente cambia, el destino también cambiará. Serán necesarios otros métodos si desea un objeto completamente nuevo en la memoria.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign