Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Wait until all assets are loaded

In a React.js project, I'm fetching svgs inside of the componentWillMount() lifecycle method via a function called loadAllAssets(). These are then saved inside of the user's localStorage.

(1) Is there a more elegant way of checking whether all requested svg files have been indeed saved inside localStorage other than iterating over the number of requests made and comparing them to the content of localStorage?

(2) Is there a nicer way to prevent the initialization of componentDidMount as long as resources are still loading other than wrapping the entire code in a conditional? I am using Redux so that would come to mind as well but seems to me like using a sledgehammer to crack a nut.

index.js

import { loadAllAssets } from './utils/loadAllAssets';

class AppContainer extends React.Component {
  componentWillMount() {
    loadAllAssets();
  }
//...
}
ReactDOM.render(<Provider store={store} ><AppContainer /></Provider>, 
document.getElementById('root'));

loadAllAssets.js

import { ajaxSVG } from './gfAssetsLoader';

export const loadAllAssets = () => {
  /* write to localStorage */
  ajaxSVG('closeScene', '/assets/svg/close-scene-ani.svg');
//...
}

gfAssetsLoader.js

export const ajaxSVG = (assetName, path) => {
  try {
    let request = new XMLHttpRequest();
    request.open("GET", path, true);
    request.onload = function (e) {
      if( request.status >= 200 && request.status < 400 ) {
        let data = request.responseText;
        localStorage.setItem(assetName, data);
      } else console.log('Bad request. request status: ' + request.status);
    }
    request.send();
  }
  catch (e) {
    console.log(e);
  }
};
like image 510
gnzg Avatar asked Oct 15 '17 16:10

gnzg


People also ask

How do you have a loading screen until all my components are mounted in React?

Just show a static loader before the UI is mounted But to just show something until mounted you just have to put something inside the div you will render the react tree into. Once react completes its render everything inside that element will be replaced.

How do you wait for a component to load in React?

To wait for a ReactJS component to finish updating, we use a loading state in our react application by use of the conditional rendering of the component. This can be achieved by the use of the useState and useEffect hooks in the functional components.

How do you check if page is fully loaded React?

ReactDOM. render(<MyElement />, document. getElementById('root'), () => { console. log('page is loaded'); }) The function runs once the page is loaded.


1 Answers

1-

export const loadAllAssets = () => {
  /* write to localStorage */
  return ajaxSVG('closeScene', '/assets/svg/close-scene-ani.svg');
  //...
}

export const ajaxSVG = (assetName, path) => {
  return new Promise((resolve, reject) => {
    try {
      let request = new XMLHttpRequest();
      request.open("GET", path, true);
      request.onload = function (e) {
        if( request.status >= 200 && request.status < 400 ) {
          let data = request.responseText;
          localStorage.setItem(assetName, data);
          resolve();
        } else reject('Bad request. request status: ' + request.status);
      }
      request.send();
    }
    catch (e) {
      reject(e);
    }
  });
};

Now you can concatenate a .then to loadAllAssets() and change the state there.

2- To show the a loading state just create a state of loading and change it to false when the data loaded, so it will show a loader while the data is loading and after it's done it will show the data.

import { loadAllAssets } from './utils/loadAllAssets';

class AppContainer extends React.Component {
  constructor() {
    super();

    this.state = {
       loading: false
    };
  }

  componentWillMount() {
    loadAllAssets()
    .then(() => {
      this.setState({ loading: false });
    });
  }
//...
  render() {
    if (this.state.loading) {
       return (
         <div><h1>Loading...</h1></div>
       );
    }

    return (
       //...something else
    );
  }
}
ReactDOM.render(<Provider store={store} ><AppContainer /></Provider>, 
document.getElementById('root'));
like image 146
Jesus Mendoza Avatar answered Oct 15 '22 10:10

Jesus Mendoza