2016-12-02 25 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/

相关问题