Home > database >  How to force the require() function to call each time the screen shows?
How to force the require() function to call each time the screen shows?

Time:02-21

I have a situation where on one screen (AScreen), I load JSON data from a .json file, I also have a Settings screen where the user can set 'settingA' as true or false.

AScreen (basically if settingA is set to true, load two JSON files, if settingA is false, load only one data file):

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 (
    ...
  );
};

The issue here is that if I load the app and head to AScreen, I get the correct data loaded into loadedData. However, if I then head to the settings page and change the setting then go back to AScreen, the console.log(settingA) shows the updated setting and the correct 'True' or 'False' is printed but the loadedData still contains the data from the first time I visited AScreen.

This tells me that the require() function doesn't actually get called until the screen is fully re-rendered.

Is there a better way to load JSON data than require()? Or how can I make sure require() is called every time the screen is displayed even if the screen isn't re-rendered.

I know one option would be to load all the JSON data then simply filter it based on the user's settings but in the actual app there are a lot more data files so it seems that would be a waste of resources to load all the files at once.

CodePudding user response:

Delete the require cache

delete require.cache[require.resolve('../assets/data/jsonFileA.json')];
...

CodePudding user response:

Regardless of how many ways I tried setting loadedData to {}, running the delete require.cache[] command, using let instead of const, etc. I always ended up the same with the loadedData not updating properly.

It turns out that the issue was from the Object.assign() function. Instead of using:

return Object.assign(
  require('../assets/data/jsonFileA.json'),
  require('../assets/data/jsonFileB.json')
)

I used:

return Object.assign(
  {},
  require('../assets/data/jsonFileA.json'),
  require('../assets/data/jsonFileB.json')
)

where the {} basically unsets the target, which is 'loadedData' and resets it with the new data. Without {}, the require statements only updated the location in memory where the require() function originally placed the data, therefore I wasn't getting the changes I was looking for.

Warning for anyone needing this in the future: The Object.assign() method creates a shallow copy so if the source changes, then the target also will change. Other methods will be necessary if you want a completely new object in memory.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

  • Related