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);
}
};
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.
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.
ReactDOM. render(<MyElement />, document. getElementById('root'), () => { console. log('page is loaded'); }) The function runs once the page is loaded.
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'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With