javascript - 更改时自动调整依赖状态,反之亦然

标签 javascript reactjs calendar redux

所以我正在使用 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
    }
}

reducer

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 日点击新的开始日期(请注意,它不在之前几天的范围内),因此 endDate 必须自动调整为 10 月 27 日
  • 同样,当点击所选范围之前的 endDate 时,startDate 必须自动相应调整,即所选 endDate 之前 3 天。

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

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

否则,我需要解决方法的帮助。

最佳答案

长话短说: 将添加天数函数更改为: state.model.calendar.startDate.clone().add(4, 'day')

我认为问题出在 momentjs add 函数上。 来自文档: http://momentjs.com/docs/#/manipulating/add/

Add

... Mutates the original moment by adding time.

这意味着当你这样做时 state.model.calendar.startDate.add(4, 'day') 它实际上改变了 state.model.calendar.startDate 的值。

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

关于javascript - 更改时自动调整依赖状态,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40103712/

相关文章:

javascript - React 组件在按钮 onClick 之后不显示在移动设备上,但在桌面上工作得很好

javascript - 如何从javascript中的对象列表中找到字符串的某些部分与对象的字符串值的最完美匹配?

javascript - 如何在所有图像加载后发出警报?

javascript - 在reactjs中离开页面后将值保存在表单中

javascript - 直接打开表单 View 窗口而不是日历 Odoo 10 上的摘要窗口

c# - 在 winforms 中创建日历的最佳方法是什么?

mysql - 在 sql 结果中填充空日期的最直接方法是什么(在 mysql 或 perl 端)?

javascript - 使用 getPointAtLength() 将圆添加到路径已移动

javascript - 动态添加到 Javascript 对象

javascript - 将 "this"绑定(bind)到对象中定义的函数