簡體   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