2017-10-15 156 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