繁体   English   中英

在react-redux组件中获取初始数据时显示加载器

[英]show loader while fetching initial data in react-redux component

我正在尝试在组件中进行初始提取并在获取数据时渲染Loader。 但是在isFetching变为true之前的render()调用因此我的组件闪烁(isFetching = false => isFetching = true => isFetching = false)。 我知道我可以在没有数据的情况下渲染Loader并且眨眼就会消失,但也许有人知道更优雅的解决方案?

动作/ 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));

为什么不让初始状态将isFetching设置为true 使用createStore函数创建存储时,可以传递初始状态。

此外,React文档建议在componentDidMount中获取数据:

如果需要从远程端点加载数据,这是实例化网络请求的好地方。 在此方法中设置状态将触发重新渲染。

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

在我看来足够优雅,只有三件事:

初始状态中没有files属性。

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]) } />
    );
  }

我不认为你的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/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM