2016-12-02 47 views
1

我正嘗試在數據獲取時在組件中執行初始提取並呈現Loader。但是在isFetching成爲true之前render()調用,因此我的組件閃爍(isFetching = false => isFetching = true => isFetching = false)。 我知道我可以在沒有數據的情況下呈現Loader,閃爍將消失,但也許有人知道更優雅的解決方案?顯示加載器,同時在react-redux組件中獲取初始數據

動作/ files.js

import 'whatwg-fetch'; 

import { REQUEST_FILES, RECEIVE_FILES } from '../constants' 

export function requestFiles() { 
    return { type: REQUEST_FILES }; 
} 

export function receiveFiles(files) { 
    const payload = files; 
    return { payload:payload, type: RECEIVE_FILES }; 
} 

export function getFile(hash) { 
    return dispatch => { 
    dispatch(requestFiles()); 
    fetch('/api/files/'+hash+'/info', { 
     method: 'GET', 
     }) 
     .then(response => response.json()) 
     .then(data => { 
     if (data.error) { 
     } 
     else { 
      dispatch(receiveFiles([data])); 
     } 
     }) 
     .catch(error => { console.log('request failed', error); }); 
    } 
} 

減速器/ files.js

import { REQUEST_FILES, RECEIVE_FILES } from '../constants' 

var initialState = { 
    items: [], 
    isFetching: false 
} 

const files = (state = initialState, action) => { 
    switch (action.type) { 
    case RECEIVE_FILES: { 
     return { ...state, isFetching:false, items: action.payload }; 
    } 
    case REQUEST_FILES: { 
     return { ...state, isFetching:true }; 
    } 
    default: 
     return state; 
    } 
} 

export default files; 

組件/智能/ fileboard.jsx

require('styles/app.scss'); 

import React from 'react'; 
import { Link } from 'react-router' 
import { bindActionCreators } from 'redux' 
import { connect } from 'react-redux' 

import * as filesActions from '../../actions/files' 

import Loader from '../dumb/loader' 
import withBoard from './board' 
import DumbFileboard from '../dumb/fileboard' 


let getFileSrc = require('config').default.getFileSrc; 

const mapStateToProps = (state) => { 
    return { 
    files: state.files 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    filesActions: bindActionCreators(filesActions, dispatch) 
    } 
} 


class Fileboard extends React.Component { 

    componentWillMount() { 
    if (this.props.files.items.length === 0) { 
     this.props.filesActions.getFile(this.props.params.hash); 
    } 
    } 

    constructor(props) { 
    super(props); 
    } 

    render() { 
    return this.props.files.isFetching ? Loader : (
     <DumbFileboard fileSrc={ getFileSrc(this.props.files.items[0]) } /> 
    ); 
    } 
} 


export default connect(mapStateToProps, mapDispatchToProps)(withBoard(Fileboard)); 

回答

0

爲什麼不讓初始狀態有isFetching設爲true?當您使用createStore函數創建商店時,您可以傳遞初始狀態。

此外,陣營文檔中componentDidMount建議取數據:

如果你需要從遠程端點加載數據,這是實例化網絡請求的好地方。在此方法中設置狀態將觸發重新渲染。

https://facebook.github.io/react/docs/react-component.html#componentdidmount

+0

我不能這樣做,因爲獲取時的情況下,不需要(例如,如果數據已被加載到前一頁)。 – ponyeatsrainbow

+0

只要頁面共享相同的商店,您可以從整體狀態(即如果數據存在=>不需要獲取並且isFetching爲false)中獲得'isFetching'? –

0

在我看來是不夠優雅,只做三件事:

有在初始狀態下沒有文件屬性。

const mapStateToProps = (state) => { 
    return { 
    files: state.files 
    } 
} 

爲什麼不使用狀態的isFetching屬性?

const mapStateToProps = (state) => { 
    return { 
    files: state.files, 
    isFetching: state.isFetching 
    } 
} 

然後

render() { 
    const { isFetching } = this.props; 

    return (
     isFetching ? 
     Loader 
     : 
     <DumbFileboard fileSrc={ getFileSrc(this.props.files.items[0]) } /> 
    ); 
    } 
0

我不認爲你的Loader是越來越呈現過(但你顯示一個空白的孩子,直到數據被加載,那麼孩子獲取數據,並呈現更多的東西)。

取而代之的是,

render() { 
    return this.props.files.isFetching ? Loader : (
     <DumbFileboard fileSrc={ getFileSrc(this.props.files.items[0]) } /> 
    ); 
    } 

你需要這個:

render() { 
    return this.props.files.isFetching ? <Loader/> : (
     <DumbFileboard fileSrc={ getFileSrc(this.props.files.items[0]) } /> 
    ); 
    } 

注意失蹤</>


看到這個小提琴(的情況下的模擬): https://jsfiddle.net/free_soul/49bdw76z/

和固定一個有工作裝載機:https://jsfiddle.net/free_soul/u0v8e0zg/

相關問題