[英]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.