2017-10-15 153 views
2

在React.js项目中,我通过名为loadAllAssets()的函数在componentWillMount()生命周期方法中获取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); 
    } 
}; 
+0

不应该在componentDidMount中完成ajax请求吗? –

+1

为什么不使用承诺?在渲染应用程序容器之前,为什么不先装载svg图像,然后才能在promise链完成之后才能实际渲染应用程序 – Maru

回答

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

如果您不想要,也可以使用redux-thunk(或任何等效库)管理组件状态内的加载。 –

+0

是的,您也可以在redux存储区内创建一个状态,并在ajax调用完成时发送操作。通过这种方式,您可以在所有组件中重新使用来自于redux商店的加载状态 –

+0

太棒了!正是我在找的东西。 – gnzg