首页 文章

React - 表单组件中状态的最佳实践?

提问于
浏览
0

我正试图了解有关反应组件状态的最佳实践 . 我开始通过编写TextField组件来创建表单,如下所示

var TextField = React.createClass({
    render: function() {
        const {value, title, placeholder} = this.props;
        return (<div>
            {title}
            <input type="text"
                value={value}
                placeholder={placeholder}
                onChange={this.handleChange} />
        </div>);
    },

    handleChange (evt){
        this.props.onChange(evt.target.value);
    }
});

这是一个受控制的组件 . 因此父容器必须为via输入中的输入传递值,并在发生更改时更改该值 . 这似乎是通常的做法 .

当我想创建一个数字字段时,我的问题出现了 . 对于此示例,假设我的数字字段将允许输入非数字字符(该字段不会验证) . 我不喜欢在父母中验证该字段的想法,所以这就是我写的

var NumericField = React.createClass({

    getInitialState: function(){
        return{
            value : ""
        }
    },

    componentWillReceiveProps: function(nextProps) {
        if(this.validate(nextProps.value)){
            this.setState({value:nextProps.value});
        }
    },

    validate : function(input) {
        return !isNaN(input);
    },

    render: function() {
        const {value} = this.state;
        const {title} = this.props;
        return (<div>
            {title}
            <input type="text"
                value={value}
                onChange={this.handleChange} />
        </div>);
    },

    handleChange (evt){
        this.setState({value:evt.target.value});
        if(this.validate(evt.target.value)){
            this.props.onChange(evt.target.value);
        }
    }
});

这允许父级设置值并通过“value”prop更新它,但“onChange”prop只会在内容有效时触发 . 我觉得我每次都使用不同的模式,这并不好 . 不确定这是否是一种有效的感觉?

我想我只是想问一下我对数字字段的方法是否合理,或者是否有更好的模式可供遵循?

万一有人想知道为什么我想要一个数字字段以这种方式工作,我不这样做,这只是一个简化的例子 . 一个更有效的例子是json的文本区域,当内容是有效的json时,它只调用onChange .

感谢任何反馈

1 回答

  • 2

    通过传递道具来设置状态通常是不受欢迎的 . 道具应该是不可变的(就像你的NumericField组件的 Headers )如果你想设置一个初始值它应该来自控制器或存储父组件从中得到它,例如 .

    getInitialState() {
      return({
        value: FormDataStore.getInitialNumericFieldValue()
      });
    }
    

    之后,对值的任何更改都应由NumericField组件处理 . 如果您需要在设置新状态之前进行验证,例如 .

    handleChange(evt) {
      if (this.validate(evt.target.value)){
        this.setState({
          value: evt.target.value
        });
        /* You can also pass the new validated value
           up to the parent component to hold on to
           till you're ready to process the form*/
        this.props.onChange(evt.target.value);
      }
    }
    

    您的状态现在只能保持(并且随后父组件将只接收)最后一个经过验证的值,因此如果this.state.value ===输入,您甚至可以显示有效/无效消息,但这是额外的

    顺便说一句,您的TextField组件也应遵循此模式 . 将更改后的值传递给父级只是为了让它作为一个道具再次传递下去,这会破坏拥有子组件的目的 . 在这种情况下,我将在父组件中使用JSX(和任何验证过程),而不是抽象子项 . 除非儿童组件可以重复使用 . 但是我仍然让孩子处理自己的状态 .

相关问题