繁体   English   中英

更改时自动调整相关状态,反之亦然

[英]Auto adjust dependent state and vice versa when changing

因此,我将Airbnb的react-dates库用于日历:

零件

export const Calendar = ({setDates, startDate, endDate, setFocused, focusedInput}) => {
return (
    <div className="input-group">
        <div className="input-group_addon">
            <i className="icon-date-inactive" aria-hidden="true"></i>
        </div>
        <DateRangePicker
            startDate={startDate}
            endDate={endDate}
            focusedInput={focusedInput}
            displayFormat="ddd, D MMM"
            onDatesChange={setDates}
            onFocusChange={setFocused}
        />
    </div>
    )
}

容器

const mapStateToProps = (state) => {
    return {
        startDate: state.model.model.calendar.startDate,
        endDate: state.model.model.calendar.endDate,
        focusedInput: state.model.model.calendar.focusedInput
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        setDates: (dates) => {
            dispatch(marketplaceSetDates(dates.startDate, dates.endDate));
        },
        setFocused: (focusedInput) => {
            dispatch(marketplaceSetFocused(focusedInput));
        }
    }
}

export const CalendarContainer = connect(mapStateToProps, mapDispatchToProps)(Calendar);

动作

export function marketplaceSetDates(startDate, endDate) {
    return {
        type: 'MARKETPLACE_MODEL_DATES_CHANGE',
        dates: {
            start: startDate,
            end: endDate
        }
    }
}

export function marketplaceSetFocused(focusedInput) {
    return {
        type: 'MARKETPLACE_MODEL_FOCUS_CHANGE',
        focusedInput: focusedInput
    }
}

减速器

let initialState = {
    model: {
        calendar: {
            startDate: moment().add(1, 'day'),
            endDate: moment().add(4, 'day'),
            focusedInput: null
        }
    },
}

export const modelReducer = (state = initialState, action) => {
    let newState = {};
    switch(action.type) {
        case 'MARKETPLACE_MODEL_FOCUS_CHANGE':
            newState = Object.assign({}, state);
            newState.model.calendar.focusedInput = action.focusedInput;
            return newState;

        case 'MARKETPLACE_MODEL_DATES_CHANGE':
            newState = Object.assign({}, state);

            newState.model.calendar.startDate = (action.dates.start === null) ?
            state.model.calendar.startDate : action.dates.start;

            newState.model.calendar.endDate = (action.dates.end === null) ?
            state.model.calendar.startDate.add(4, 'day') : action.dates.end;

            return newState;
    }
    return state;
}

我们日历的一条规则是,每当用户选择新的startDateendDate ,它都必须自动调整为至少相隔3天

例如,您可以看到,初始状态将日期设置为明天和现在的4天。

  • 所以应该是10月19日-> 10月22日
  • 如果我在10月24日单击一个新的startDate (请注意 ,它endDate以前的日期 范围内) ,则endDate必须自动调整为10月27日
  • 单击选定范围之前的endDate也是如此, startDate必须在选定endDate之前3天进行相应的自动调整。

但是使用我当前的代码,当我单击startDatestartDateendDate都设置为3天后 ,这只能是endDate的值。

我怀疑这背后的原因是由于redux的状态突变是异步的,因此state.model.calendar.startDate.add(4, 'day')首先位于newState.model.calendar.startDate = ... ,我的假设正确吗?

否则,我需要解决方法。

TL; DR:将添加天数功能更改为: state.model.calendar.startDate.clone().add(4, 'day')

我相信问题在于momentjs add函数。 从文档中: http : //momentjs.com/docs/#/manipulating/add/

...通过增加时间来改变原始时刻。

这意味着当您执行state.model.calendar.startDate.add(4, 'day')它实际上会更改state.model.calendar.startDate的值。

因此,理想情况下,您应该复制该时刻,然后使用clone()对其进行更改

暂无
暂无

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

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