2017-10-14 128 views
0

所以,我有一個函數,它將圖像轉換爲base64。這個函數是異步的,它在Promise.all()的幫助下轉換4個圖像,然後用接收到的字符串返回對象。所以,我輸出異步功能。下面是代碼:Redux中的異步/等待

import IMAC from '../assets/Images/devices/mac_monitor.png'; 
import MACBOOK from '../assets/Images/devices/macbook_pro.png'; 
import IPHONE_8 from '../assets/Images/devices/iphone_8.png'; 
import MSI_LAPTOP from '../assets/Images/devices/msi_laptop.png'; 

function loadImage(img) { 
    return new Promise((resolve, reject) => { 
     toDataURL(img, function (dataUrl) { 
      resolve(dataUrl); 
     }) 
    }); 
} 

function toDataURL(url, callback) { 
    const xhr = new XMLHttpRequest(); 
    xhr.onload = function() { 
     let reader = new FileReader(); 
     reader.onloadend = function() { 
      callback(reader.result); 
     }; 
     reader.readAsDataURL(xhr.response); 
    }; 
    xhr.open('GET', url); 
    xhr.responseType = 'blob'; 
    xhr.send(); 
} 

const IMAC_IMG_BASE64 = loadImage(IMAC); 
const MACBOOK_IMG_BASE64 = loadImage(MACBOOK); 
const MSI_IMG_BASE64 = loadImage(MSI_LAPTOP); 
const PHONE_IMG_BASE64 = loadImage(IPHONE_8); 

export async function loadAllImages() { 
    const result = await Promise.all([IMAC_IMG_BASE64, MACBOOK_IMG_BASE64, MSI_IMG_BASE64, PHONE_IMG_BASE64]); 
    return [ 
     { 
      id: 0, 
      device: "Apple iMac", 
      image: result[0], 
      styles: { 
       carousel_item: { 
        width: "41.6vw", 
        height: "auto", 
        top: "-4.095vw", 
        left: "-0.13vw" 
       }, 
       carousel: { 
        height: "38vw", 
        margin: "50px 0" 
       }, 
       device: { 
        width: "46.5vw", 
        height: "38vw", 
        marginLeft: "-23.25vw" 
       } 
      } 
     }, 
     { 
      id: 1, 
      device: "Apple Macbook Pro", 
      image: result[1], 
      styles: { 
       carousel_item: { 
        width: "37vw", 
        height: "auto", 
        top: "-4.4vw", 
        left: ".6vw" 
       }, 
       carousel: { 
        height: "38vw", 
        margin: "50px 0" 
       }, 
       device: { 
        width: "55vw", 
        height: "30vw", 
        marginLeft: "-27.5vw" 
       } 
      } 
     }, 
     { 
      id: 2, 
      device: "MSI GP72VR 7RFX", 
      image: result[2], 
      styles: { 
       carousel_item: { 
        width: "35vw", 
        height: "auto", 
        top: "-5.8vw", 
        left: ".5vw" 
       }, 
       carousel: { 
        height: "38vw", 
        margin: "50px 0" 
       }, 
       device: { 
        width: "50vw", 
        height: "34vw", 
        marginLeft: "-25vw" 
       } 
      } 
     }, 
     { 
      id: 3, 
      device: "Iphone 8", 
      image: result[3], 
      styles: { 
       carousel_item: { 
        width: "14vw", 
        height: "auto", 
        top: "-8.2vw", 
        left: "0" 
       }, 
       carousel: { 
        height: "38vw", 
        margin: "50px 0" 
       }, 
       device: { 
        width: "17.7vw", 
        height: "34vw", 
        marginLeft: "-8.85vw" 
       } 
      } 
     }, 
    ]; 
} 

然後,我有這樣的行動者,即異步,在這裏我從這個函數(loadAllImages())接收到的數據,然後我叫調度(PS - 我使用redux-咚)

export const loadConfigs =() => async dispatch => { 
const data = await loadAllImages(); 
dispatch({type: "LOAD_DATA", payload: data}); 
}; 

另外,我有減速機,在那裏我返回有效載荷與對象,從所謂的調度

export default (sliderConfig = null, action) => { 
    const {type, payload} = action; 
    switch(type){ 
     case "LOAD_DATA": 
      return payload; 
    } 

    return sliderConfig; 
} 

接到主容器App.js裏面,我把這種交流的康波內nentDidMount() (別看fetchUser(),它並沒有在這方面重要)

componentDidMount() { 
     this.props.fetchUser(); 
     this.props.loadConfigs(); 
    } 

而且,當時我有分量,在這裏我使用這個數據,這從異步交流好評。 (不要看appDesign(),在這方面沒關係)

import React, {Component, PureComponent} from 'react'; 
import appDesign from '../../../decorators/scroll_resize_decorator'; 
import Slider from './Slider'; 
import {connect} from 'react-redux'; 
import * as actions from '../../../actions'; 

//Hint: Use container for the images in the slider 
//Because errors with movement is appeared 
class BlockFour extends Component { 

    render() { 

     if (this.props.sliderElements) { 
      const {sliderElements, width, config, selectConfig} = this.props; 
      return (
       <div className="blockfive"> 
        <div className="blockfive--inner"> 
         <div className="blockfive__container"> 
          <div className="blockfive__container__header"> 
           <div className="blockfive__container__header__container"> 
            <h1>Application Gallery</h1> 
            <p> 
             Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
             A aliquid blanditiis consequuntur debitis deserunt eaque eligendi 
            </p> 
            <div className="blockfive__header--divider"></div> 
           </div> 
          </div> 
          <div className="blockfive__container__device"> 
           <h2> 
            Choose your device to what screenshots 
           </h2> 
           <ul className="tabs"> 
            { 
              sliderElements.map(item => 
              <li 
               key={item.id} 
               className="tab" 
               > 
               <a href="#" 
                onClick={ 
                 () => selectConfig(item.id) 
                } 
               > 
                {item.device} 
               </a> 
              </li> 
             ) 
            } 
           </ul> 
          </div> 
          <div className="blockfive__container__gallery"> 
           { 
             <Slider 
             width={width} 
             styles={sliderElements[config].styles} 
             device_image={sliderElements[config].image} 
            /> 
           } 
          </div> 
         </div> 
        </div> 
       </div> 
      ); 
     } 

     return null 
    } 
} 

const mapStateToProps = ({sliderElements, config}) => { 
    return { 
     sliderElements, 
     config 
    } 
}; 

export default connect(mapStateToProps, actions)(appDesign(BlockFour)); 

所以,這個語法正在工作,一切正在加載和工作。所以,我有一個問題:什麼是正確的方式來獲取AC中的異步數據,然後將它們傳遞給reducer,然後加載到組件中。我不想在組件中使用if語句。

我讀過關於異步/等待AC的指南以及如何使用它們,但我不完全理解如何在我的情況下使用它。你能否給我一個簡要的指導,如何在這裏實現它。謝謝!

+0

您在請求的回調中提出請求(提取或您要使用的任何庫),然後您將該數據發送給reducer –

+0

這幾乎就是您在做什麼。根本沒有問題。 – WilomGfx

+0

@WilomGfx它的工作原理,是的,但我讀了一些指南,其中人們寫了三個AC,即DATA_IS_FETCHING,DATA_IS_FETCHED和DATA_IS_LOADED。我不明白這一點,我應該在這裏使用它 – Remzes

回答

1

我個人和大多數人都會關注這個approach。它完全個人化,不會在您的應用中發生很大變化,但可能會讓您的生活更輕鬆。

{ type: 'FETCH_POSTS_REQUEST' } 
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' } 
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } } 

這樣,您的用戶界面和連接到商店的應用的其他部分可以根據狀態採取相應的行爲。

Exemples包括:顯示當FETCH_SMTH_REQUEST被觸發,你的狀態變化以獲取和顯示錯誤時FETCH_SMTH_FAILURE和你在你的狀態得到error加載圖標或消息。