如何使用React.JS正确验证输入值?

我有一个简单的表格。所有组件和状态都保存在Page组件中。有2个显示标题和3个输入字段。第一个输入应该是文本,第二个和第三个输入应该是整数。当用户输入错误的数据类型时,我想在输入字段旁边弹出一条错误消息。我的问题与React.JS中的最佳实践有关

谁认为该值有效?我想输入字段的唯一工作就是将值引导回保持状态的组件,这是否意味着只有Page可以确定值是否有效?

然后应该如何显示弹出窗口?Page是否应该触发将通过perp传递的新布尔状态元素,该元素将告诉Adaptive_Input显示错误消息?

JSFiddle

JS:

/**
 * @jsx React.DOM
 */
var Adaptive_Input = React.createClass({ 
    handle_change: function(){
        var new_text = this.refs.input.getDOMNode().value;
        this.props.on_Input_Change(new_text);
    },
    render: function(){
        return (
                <div className='adaptive_placeholder_input_container'>
                    <input 
                        className="adaptive_input"
                        type="text" 
                        required="required" 
                        onChange= {this.handle_change}
                        ref="input"
                    ></input>
                    <label
                        className="adaptive_placeholder"
                        alt={this.props.initial}
                        placeholder={this.props.focused}
                    ></label>
                </div>              
                );
    }
});

var Form = React.createClass({
    render: function(){
        return (
                <form>
                    <Adaptive_Input
                        initial={'Name Input'}
                        focused={'Name Input'}
                        on_Input_Change={this.props.handle_text_input}
                    />
                    <Adaptive_Input
                        initial={'Value 1'}
                        focused={'Value 1'}
                        on_Input_Change={this.props.handle_value_1_input}
                    />
                    <Adaptive_Input
                        initial={'Value 2'}
                        focused={'Value 2'}
                        on_Input_Change={this.props.handle_value_2_input}
                    />
                </form>
                );
    }
});

var Page = React.createClass({
    getInitialState: function(){
        return {
            Name : "No Name",
            Value_1 : '0',
            Value_2 : '0',
            Display_Value: '0'
        };
    },
    handle_text_input: function(new_text){
        this.setState({
                Name: new_text
            });
    },
    handle_value_1_input: function(new_value){
        console.log("===");
        var updated_display = parseInt(new_value) + parseInt(this.state.Value_2);
        updated_display = updated_display.toString();
        this.setState({
                Display_Value: updated_display 
            });
    },
    handle_value_2_input: function(new_value){
        var updated_display = parseInt(this.state.Value_1) + parseInt(new_value);
        updated_display = updated_display.toString();
        this.setState({
                Display_Value: updated_display
            });
    },
    render: function(){
        return(
                <div>
                    <h2>{this.state.Name}</h2>
                    <h2>Value 1 + Value 2 = {this.state.Display_Value}</h2>
                    <Form
                        handle_text_input={this.handle_text_input}
                        handle_value_1_input = {this.handle_value_1_input}
                        handle_value_2_input = {this.handle_value_2_input}
                    />
                </div>
        );
    }
});

React.renderComponent(<Page />, document.body);
NearAStafan2020/03/18 15:46:11

有时您可以在应用程序中具有多个具有相似验证的字段。在这种情况下,建议您创建用于保留此验证的通用组件字段。

例如,假设您在应用程序中的几个地方都必须输入文本。您可以创建一个TextInput组件:

constructor(props) {
    super(props); 
    this.state = {
        touched: false, error: '', class: '', value: ''
    }
}

onValueChanged = (event) => {
    let [error, validClass, value] = ["", "", event.target.value];

    [error, validClass] = (!value && this.props.required) ? 
        ["Value cannot be empty", "is-invalid"] : ["", "is-valid"]

    this.props.onChange({value: value, error: error});

    this.setState({
        touched: true,
        error: error,
        class: validClass,
        value: value
    })
}

render() {
    return (
        <div>
            <input type="text"
                value={this.props.value}
                onChange={this.onValueChanged}
                className={"form-control " + this.state.class}
                id="{this.props.id}"
                placeholder={this.props.placeholder} />
            {this.state.error ?
                <div className="invalid-feedback">
                    {this.state.error}
                </div> : null
            }
        </div>
    )
}

然后,您可以在应用程序中的任何位置使用这样的组件:

constructor(props) {
    super(props);
    this.state = {
        user: {firstName: '', lastName: ''},
        formState: {
            firstName: { error: '' },
            lastName: { error: '' }
        }
    }
}

onFirstNameChange = (model) => {
    let user = this.state.user;
    user.firstName = model.value;

    this.setState({
        user: user,
        formState: {...this.state.formState, firstName: { error: model.error }}
    })
}

onLastNameChange = (model) => {
    let user = this.state.user;
    user.lastName = model.value;

    this.setState({
        user: user,
        formState: {...this.state.formState, lastName: { error: model.error }}
    })
}


onSubmit = (e) => {
   // submit logic
}


render() {
    return (
        <form onSubmit={this.onSubmit}>
            <TextInput id="input_firstName"
                value={this.state.user.firstName}
                onChange={this.onFirstNameChange}
                required = {true}
                placeholder="First name" />

            <TextInput id="input_lastName"
                value={this.state.user.lastName}
                onChange={this.onLastNameChange}
                required = {true}
                placeholder="Last name" />

            {this.state.formState.firstName.error || this.state.formState.lastName.error ?
                <button type="submit" disabled className="btn btn-primary margin-left disabled">Save</button>
                : <button type="submit" className="btn btn-primary margin-left">Save</button>
            }

        </form>
    )
}

好处:

  • 您无需重复验证逻辑
  • 表单中的代码更少-更具可读性
  • 其他通用输入逻辑可以保留在组件中
  • 您遵循React规则,即组件应该尽可能的笨

参考 https://webfellas.tech/#/article/5

凯理查德番长2020/03/18 15:46:11

还有另一个问题form-container -npm

番长Near2020/03/18 15:46:11

我最近花了一个星期研究许多解决方案,以验证我在应用程序中的表单。我从最受注视的人开始,但是找不到一个按预期工作的人。几天后,我变得非常沮丧,直到找到了一个非常新的惊人插件:https : //github.com/kettanaito/react-advanced-form

开发人员反应灵敏,在我研究之后,他的解决方案值得成为我眼中最受关注的解决方案。希望对您有所帮助,您会感激不尽。

Mandy梅Green2020/03/18 15:46:11

我写了这个库,它允许您包装表单元素组件,并允许您以以下格式定义验证器:

<Validation group="myGroup1"
    validators={[
            {
             validator: (val) => !validator.isEmpty(val),
             errorMessage: "Cannot be left empty"
            },...
        }]}>
            <TextField value={this.state.value}
                       className={styles.inputStyles}
                       onChange={
                        (evt)=>{
                          console.log("you have typed: ", evt.target.value);
                        }
                       }/>
</Validation>
小小飞云2020/03/18 15:46:11

首先,这是我将在下面提及的示例:http : //jsbin.com/rixido/2/edit

如何使用React.JS正确验证输入值?

随你怎么便。React是用于渲染数据模型的。数据模型应该知道什么是有效的。您可以使用Backbone模型,JSON数据或任何您想要表示数据及其错误状态的东西。

进一步来说:

React通常与您的数据无关。它用于呈现和处理事件。

遵循的规则是:

  1. 元素可以更改其状态。
  2. 他们不能改变道具。
  3. 他们可以调用将更改顶级道具的回调。

如何决定某个东西应该是道具还是国家?考虑一下:您的应用程序中除文本字段之外的任何部分都想知道输入的值是否错误?如果否,则将其设为状态。如果是的话,那应该是一个道具。

例如,如果您想要一个单独的视图来呈现“此页面上有2个错误”。那么顶级数据模型就必须知道您的错误。

该错误应该存在何处?
例如,如果您的应用正在渲染Backbone模型,则模型本身将具有您可以使用的validate()方法和validateError属性。您可以渲染其他可以执行相同操作的智能对象。React还说,要尽量减少道具并生成其余数据。因此,如果您有一个验证器(例如https://github.com/flatiron/revalidator),则您的验证可能会滴落下来,并且任何组件都可以通过匹配验证来检查道具,以查看其是否有效。

这在很大程度上取决于您。

(我个人使用的是Backbone模型,并在React中渲染它们。我有一个顶级错误警报,可以显示是否有错误,并描述错误。)