在ReduxForm中使用规范化器会导致表单始终变脏

时间:2016-05-24 21:52:22

标签: reactjs redux redux-form

我正在使用规范化器将来自rest api的ISO 8601日期/时间值(例如 2016-05-24T20:38:34+00:00)转换为日期(例如 2016-05-24)。我的规范化器看起来像这样:

export const dateNormalizer = function(value){
    if(value)
        return moment(value).format("YYYY-MM-DD");
    };

我还使用规范化器进行货币转换(例如确保它只是数字等)。

我遇到的问题是这导致表单总是变脏。换句话说,只要加载初始状态(通过initialValues中的mapStateToProps),this.props.dirty始终返回true。即使调度reset也不会导致dirty=false

有没有办法克服这个问题?我遇到的问题是我希望能够向用户显示一个警告,即他们将要放弃他们的更改,而不必为每个输入字段实现我自己的onChange覆盖,现在他们'总是警告我们放弃了改变。

1 个答案:

答案 0 :(得分:6)

使用ReduxForm内置的normalizer框架无法找到解决方案。相反,我使用了this suggestion from the issues list并构建了我自己的掩码/规范化程序组件,以便在它们显示之前调整值,但也要确保存储获取原始值。这也有一个额外的好处,就是让我在内部代表货币作为Number,而在ui中代表String(带有$和千位分隔符)。这是代码,以防任何人最终想要做类似的事情:

import React, { Component } from 'react'

const isSupportedType = (type) => {
    return type !== 'checkbox' && type !== 'file' && type !== 'select-multiple';
};

class MaskedInput extends Component {

    normalize(value, mask, normalize, originalBlur, originalChange){
        return {
            value: mask(value),
            onBlur: (event) => {
                if (isSupportedType(event.target.type)){
                    originalBlur(normalize(event.target.value))
                }else{
                    originalBlur(event);
                }

            },
            onChange: (event) => {
                if (isSupportedType(event.target.type)){
                    originalChange(normalize(event.target.value));
                }else{
                    originalChange(event);
                }

            }

        }
    }

    render(){

        const {
            mask,
            normalizer,
            value,
            onBlur,
            onChange,
            ...rest
            } = this.props;

        return <input {...rest} {...this.normalize(value, mask, normalizer, onBlur, onChange)} />
    }

}

MaskedInput.propTypes = {
    mask: React.PropTypes.func,
    normalizer: React.PropTypes.func
};

export default MaskedInput;