React:等到所有资产都加载完毕

时间:2017-10-15 16:24:16

标签: javascript reactjs asynchronous svg

在React.js项目中,我通过名为componentWillMount()的函数在loadAllAssets()生命周期方法中获取svgs。然后将它们保存在用户的localStorage中。

(1)是否有更优雅的方法来检查所有请求的svg文件是否确实已保存在localStorage中,而不是迭代所请求的数量并将它们与localStorage的内容进行比较?

(2)有没有更好的方法来阻止componentDidMount的初始化,只要资源仍在加载,而不是将整个代码包装在条件中?我正在使用Redux,所以我也会想到这一点,但在我看来,就像使用大锤来破解坚果一样。

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

1 个答案:

答案 0 :(得分:1)

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

现在你可以将.then连接到loadAllAssets()并更改那里的状态。

2-要显示加载状态,只需创建一个加载状态,并在加载数据时将其更改为false,这样它将在加载数据时显示加载器,并在完成后显示加载状态将显示数据

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'));