我正在尝试在尚未提取数据时设置Loader。如果数据只上传一个,这种情况很容易(逻辑在这里:设置一个标志isFetching为true,当从redux接收时将其设置为false)。但我的情况有点不同。我想多次获取我的数据来更新我的日历组件。所有这些都是通过带有axios包的redux完成的。
看起来像是:
我的reducer在我的axios请求完成后添加isFetching标志(商店已更新):
import React, { Component } from 'react';
import Calendar from 'react-calendar';
import ChooseHour from './ChooseHour';
import { connect } from 'react-redux';
import * as actions from '../actions';
class Calendario extends Component {
state = { showHours: false, disabledDates: null}
componentDidMount() {
const { chosenRoom } = this.props;
const date = new Date();
const reqMonth = date.getMonth() + 1;
const reqYear = date.getFullYear();
this.props.activeMonthYearToPass({reqMonth, reqYear, chosenRoom});
}
onChange = date => this.setState({ date }, () => {
const { chosenRoom, isBirthday } = this.props;
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const fullDate = `${year}/${month}/${day}`;
const roomAndDayObj = {fullDate, chosenRoom, isBirthday};
this.props.sendRoomAndDay(roomAndDayObj);
}
);
onClickDay(e) {
const { chosenRoom } = this.props;
!chosenRoom ? this.setState({ errorMsg: "Wybierz pokój", showHours: false}) :
this.setState({ showHours: true, errorMsg:'' });
}
passActiveDate(activeDate) {
const { chosenRoom } = this.props;
const reqMonth = activeDate.getMonth() + 1;
const reqYear = activeDate.getFullYear();
this.setState({ pending: true},
() => this.props.activeMonthYearToPass({reqMonth, reqYear, chosenRoom})
);
this.props.passDateDetails({reqMonth, reqYear});
}
render() {
const { fullyBookedDays, isBirthday } = this.props;
const { errorMsg, pending } = this.state;
return (
<div>
<div className="calendarsCont">
<Calendar
onChange={this.onChange}
onClickDay={(e) => this.onClickDay(e)}
onActiveDateChange={({ activeStartDate }) => this.passActiveDate(activeStartDate)}
value={this.state.date}
locale="pl-PL"
tileDisabled={({date, view}) =>
(view === 'month') &&
fullyBookedDays && fullyBookedDays.fullyBooked.some(item =>
date.getFullYear() === new Date(item).getFullYear() &&
date.getMonth() === new Date(item).getMonth() -1 &&
date.getDate() === new Date(item).getDate()
)}
/>
}
</div>
<p style={{color: 'red'}}>{errorMsg}</p>
<div>
{this.state.showHours ?
<ChooseHour chosenDay={this.state.date} chosenRoom={this.props.chosenRoom} isBirthday={isBirthday}/> :
null}
</div>
</div>
)
}
}
function mapStateToProps({fullyBookedDays}){
return {
fullyBookedDays,
}
}
export default connect (mapStateToProps, actions)(Calendario);
组件看起来像那样:
{{1}}
因此axios请求会多次出现新值。 在这种情况下你使用什么样的策略?
谢谢!
答案 0 :(得分:0)
每当有多个抓取请求,或者甚至多个动作指示异步发生并且需要存储在状态的一部分时,我使用计数器:
export default function(state = {fetchCount: 0}, action){
switch(action.type){
case FETCHING_THING:
return Object.assign({}, state, {
fetchCount: state.fetchCount + 1
})
case FETCHING_THING_DONE:
return Object.assign({}, state, {
fetchCount: state.fetchCount - 1,
fullyBooked: action.payload
}
default:
return state;
}
}
然后,您只需检查mapstatetoprops中的fetchCount > 0
即可。
function mapStateToProps({fullyBookedDays, fetchCount}){
return {
fullyBookedDays,
isLoading: fetchCount > 0
}
}
答案 1 :(得分:-1)
请以下面的例子为例,Redux-thunk样式动作用于包装多个axios请求并将它们全部发送。
//axios call2
function getData1() {
return axios.get('/data1');
}
//axios call2
function getData2() {
return axios.get('/data2');
}
//redux-thunk action creator
function getFullData() {
return (dispatch, getState) => {
axios.all([getData1(), getData2()])
.then(axios.spread(function (acct, perms) {
//call normal action creator
dispatch(fetchData1())
dispatch(fetchData2())
}));
};
}
//normal actioncreator
function fetchData1(data)
{
return {type: "FETCH_DATA1", payload: data}
}
//normal actioncreator
function fetchData2(data)
{
return {type: "FETCH_DATA2", payload: data}
}
//reducer1:
function reducer1 (state = defaultedState ,action){
return Object.assign({},{...state, data: action.payload, isFetching: false} )
}
//reducer2:
function reducer2 (state = defaultedState ,action){
return Object.assign({},{...state, data: action.payload, isFetching: false} )
}
//component:
mapStateToProps = function(state){
return {
data1: state.data1.data,
data2: state.data2.data,
isFetching1: state.data1.isFetching,
isFetching2: state.data2.isFetching
}
}
import React, { Component } from "react";
class MyComponent extends Component{
render(){
return (!data1 && isFetching1) || (!data2 && isFetching2) ? <Loading> : <DataComponent>
}
}
connect(mapStateToProps)(MyComponent)
&#13;