Vraag Hoe invoerwaarden correct te valideren met React.JS?


Ik heb een eenvoudige vorm. Alle componenten en status worden bewaard in de pagina-component. Er zijn 2 displayheaders en 3 invoervelden. De eerste invoer zou tekst moeten zijn en de tweede en derde moeten ints zijn. Wanneer de gebruiker het verkeerde type gegevens invoert, wil ik dat er een foutmelding naast het invoerveld verschijnt. Mijn vragen hebben betrekking op best practices in React.JS

Wie beslist dat de waarde geldig is? Ik veronderstel dat de enige taak van het invoerveld is om de waarde terug te leiden naar de component die de staat vasthoudt, betekent dit dat alleen pagina kan bepalen of een waarde geldig is?

Hoe zou ik dan de pop-up moeten laten verschijnen? Moet pagina een nieuw Boolean-statuselement activeren dat door perp wordt doorgegeven, zodat Adaptive_Input het foutbericht onthult?

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);

64
2018-06-03 15:44


oorsprong


antwoorden:


Ten eerste, hier is een voorbeeld van wat ik hieronder zal noemen: http://jsbin.com/rixido/2/edit

Hoe invoerwaarden correct te valideren met React.JS?

Hoe je maar wilt. Reageren is voor het renderen van een gegevensmodel. Het datamodel moet weten wat geldig is of niet. U kunt Backbone-modellen, JSON-gegevens of wat dan ook gebruiken om de gegevens en de foutstatus ervan weer te geven.

Specifieker:

Reageren is over het algemeen agnostisch ten opzichte van uw gegevens. Het is voor het weergeven en behandelen van gebeurtenissen.

De te volgen regels zijn:

  1. elementen kunnen hun toestand veranderen.
  2. ze kunnen geen rekwisieten veranderen.
  3. ze kunnen een callback oproepen die de rekwisieten op het hoogste niveau verandert.

Hoe te beslissen of iets een prop of een staat moet zijn? Overweeg dit: zou ELK deel van uw app anders dan het tekstveld willen weten dat de ingevoerde waarde slecht is? Zo nee, maak er een staat van. Zo ja, dan zou het een prop moeten zijn.

Als u bijvoorbeeld een afzonderlijke weergave wilt weergeven 'U heeft 2 fouten op deze pagina'. dan moet uw fout bekend zijn bij een datamodel op topniveau.

Waar zou die fout moeten leven?
Als uw app Backbone-modellen renderde (bijvoorbeeld), zou het model zelf een methode validate () en een eigenschap Error gebruiken die u zou kunnen gebruiken. U kunt andere slimme objecten weergeven die hetzelfde zouden kunnen doen. React zegt ook dat propo's tot een minimum beperkt moeten blijven en genereert de rest van de gegevens. dus als je een validator had (bijv. https://github.com/flatiron/revalidator), dan kunnen uw validaties naar beneden vallen en kan elk onderdeel rekwisieten controleren met zijn overeenkomende validatie om te zien of het geldig is.

Het is grotendeels aan jou.

(Ik ben persoonlijk Backbone-modellen gebruiken en deze weergeven in React. Ik heb een foutmelding op het hoogste niveau die ik laat zien als er ergens een fout is die de fout beschrijft.)


73
2018-06-12 20:12



Je kunt gebruiken npm install --save redux-form

Ik schrijf een eenvoudig e-mail en verzend knop formulier, dat e-mail valideert en een formulier indient. met redux-vorm, vormt standaard standaard event.preventDefault () op html onSubmit-actie.

import React, {Component} from 'react';
import {reduxForm} from 'redux-form';

class LoginForm extends Component {
  onSubmit(props) {
    //do your submit stuff
  }


  render() {
    const {fields: {email}, handleSubmit} = this.props;

    return (
      <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
        <input type="text" placeholder="Email"
               className={`form-control ${email.touched && email.invalid ? 'has-error' : '' }`}
          {...email}
        />
          <span className="text-help">
            {email.touched ? email.error : ''}
          </span>
        <input type="submit"/>
      </form>
    );
  }
}

function validation(values) {
  const errors = {};
  const emailPattern = /(.+)@(.+){2,}\.(.+){2,}/;
  if (!emailPattern.test(values.email)) {
    errors.email = 'Enter a valid email';
  }

  return errors;
}

LoginForm = reduxForm({
  form: 'LoginForm',
  fields: ['email'],
  validate: validation
}, null, null)(LoginForm);

export default LoginForm;

10
2018-05-12 13:26



ik heb geschreven Deze bibliotheek waarmee u uw formulierelementcomponenten kunt inpakken en waarmee u uw validators kunt definiëren in de volgende indeling: -

<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>

3
2018-01-18 06:56



Je jsfiddle werkt niet meer. Ik heb het gerepareerd: http://jsfiddle.net/tkrotoff/bgC6E/40/ met behulp van React 16 en ES6 klassen.

class Adaptive_Input extends React.Component {
  handle_change(e) {
    var new_text = e.currentTarget.value;
    this.props.on_Input_Change(new_text);
  }

  render() {
    return (
      <div className="adaptive_placeholder_input_container">
        <input
          className="adaptive_input"
          type="text"
          required="required"
          onChange={this.handle_change.bind(this)} />
        <label
          className="adaptive_placeholder"
          alt={this.props.initial}
          placeholder={this.props.focused} />
      </div>
    );
  }
}

class Form extends React.Component {
  render() {
    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>
    );
  }
}

class Page extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      Name: 'No Name',
      Value_1: '0',
      Value_2: '0',
      Display_Value: '0'
    };
  }

  handle_text_input(new_text) {
    this.setState({
      Name: new_text
    });
  }

  handle_value_1_input(new_value) {
    new_value = parseInt(new_value);
    var updated_display = new_value + parseInt(this.state.Value_2);
    updated_display = updated_display.toString();
    this.setState({
      Value_1: new_value,
      Display_Value: updated_display
    });
  }

  handle_value_2_input(new_value) {
    new_value = parseInt(new_value);
    var updated_display = parseInt(this.state.Value_1) + new_value;
    updated_display = updated_display.toString();
    this.setState({
      Value_2: new_value,
      Display_Value: updated_display
    });
  }

  render() {
    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.bind(this)}
          handle_value_1_input={this.handle_value_1_input.bind(this)}
          handle_value_2_input={this.handle_value_2_input.bind(this)}
        />
      </div>
    );
  }
}

ReactDOM.render(<Page />, document.getElementById('app'));

En nu is dezelfde code gehackt met formuliervalidatie dankzij deze bibliotheek: https://github.com/tkrotoff/react-form-with-constraints => http://jsfiddle.net/tkrotoff/k4qa4heg/

http://jsfiddle.net/tkrotoff/k4qa4heg/

const { FormWithConstraints, FieldFeedbacks, FieldFeedback } = ReactFormWithConstraints;

class Adaptive_Input extends React.Component {
  static contextTypes = {
    form: PropTypes.object.isRequired
  };

  constructor(props) {
    super(props);

    this.state = {
      field: undefined
    };

    this.fieldWillValidate = this.fieldWillValidate.bind(this);
    this.fieldDidValidate = this.fieldDidValidate.bind(this);
  }

  componentWillMount() {
    this.context.form.addFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.addFieldDidValidateEventListener(this.fieldDidValidate);
  }

  componentWillUnmount() {
    this.context.form.removeFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.removeFieldDidValidateEventListener(this.fieldDidValidate);
  }

  fieldWillValidate(fieldName) {
    if (fieldName === this.props.name) this.setState({field: undefined});
  }

  fieldDidValidate(field) {
    if (field.name === this.props.name) this.setState({field});
  }

  handle_change(e) {
    var new_text = e.currentTarget.value;
    this.props.on_Input_Change(e, new_text);
  }

  render() {
    const { field } = this.state;
    let className = 'adaptive_placeholder_input_container';
    if (field !== undefined) {
      if (field.hasErrors()) className += ' error';
      if (field.hasWarnings()) className += ' warning';
    }

    return (
      <div className={className}>
        <input
          type={this.props.type}
          name={this.props.name}
          className="adaptive_input"
          required
          onChange={this.handle_change.bind(this)} />
        <label
          className="adaptive_placeholder"
          alt={this.props.initial}
          placeholder={this.props.focused} />
      </div>
    );
  }
}

class Form extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      Name: 'No Name',
      Value_1: '0',
      Value_2: '0',
      Display_Value: '0'
    };
  }

  handle_text_input(e, new_text) {
    this.form.validateFields(e.currentTarget);

    this.setState({
      Name: new_text
    });
  }

  handle_value_1_input(e, new_value) {
    this.form.validateFields(e.currentTarget);

    if (this.form.isValid()) {
      new_value = parseInt(new_value);
      var updated_display = new_value + parseInt(this.state.Value_2);
      updated_display = updated_display.toString();
      this.setState({
        Value_1: new_value,
        Display_Value: updated_display
      });
    }
    else {
      this.setState({
        Display_Value: 'Error'
      });
    }
  }

  handle_value_2_input(e, new_value) {
    this.form.validateFields(e.currentTarget);

    if (this.form.isValid()) {
      new_value = parseInt(new_value);
      var updated_display = parseInt(this.state.Value_1) + new_value;
      updated_display = updated_display.toString();
      this.setState({
        Value_2: new_value,
        Display_Value: updated_display
      });
    }
    else {
      this.setState({
        Display_Value: 'Error'
      });
    }
  }

  render() {
    return(
      <div>
        <h2>Name: {this.state.Name}</h2>
        <h2>Value 1 + Value 2 = {this.state.Display_Value}</h2>

        <FormWithConstraints ref={form => this.form = form} noValidate>
          <Adaptive_Input
            type="text"
            name="name_input"
            initial={'Name Input'}
            focused={'Name Input'}
            on_Input_Change={this.handle_text_input.bind(this)} />
          <FieldFeedbacks for="name_input">
            <FieldFeedback when="*" error />
            <FieldFeedback when={value => !/^\w+$/.test(value)} warning>Should only contain alphanumeric characters</FieldFeedback>
          </FieldFeedbacks>

          <Adaptive_Input
            type="number"
            name="value_1_input"
            initial={'Value 1'}
            focused={'Value 1'}
            on_Input_Change={this.handle_value_1_input.bind(this)} />
          <FieldFeedbacks for="value_1_input">
            <FieldFeedback when="*" />
          </FieldFeedbacks>

          <Adaptive_Input
            type="number"
            name="value_2_input"
            initial={'Value 2'}
            focused={'Value 2'}
            on_Input_Change={this.handle_value_2_input.bind(this)} />
          <FieldFeedbacks for="value_2_input">
            <FieldFeedback when="*" />
          </FieldFeedbacks>
        </FormWithConstraints>
      </div>
    );
  }
}

ReactDOM.render(<Form />, document.getElementById('app'));

De voorgestelde oplossing hier is hackish omdat ik heb geprobeerd het dicht bij de originele jsfiddle te houden. Controleer de juiste vormvalidatie met beperkingen in de vorm van een reactievorm https://github.com/tkrotoff/react-form-with-constraints#examples


2
2018-05-29 20:34



Ik heb onlangs een week lang veel oplossingen bestudeerd om mijn formulieren in een app te valideren. Ik begon met de meesten, maar ik kon niemand vinden die werkte zoals ik verwachtte. Na een paar dagen raakte ik behoorlijk gefrustreerd totdat ik een heel nieuwe en verbazingwekkende plug-in vond: https://github.com/kettanaito/react-advanced-form

De ontwikkelaar reageert erg goed en zijn oplossing is, na mijn onderzoek, de verdienste om vanuit mijn perspectief de meest aangekomene te worden. Ik hoop dat het kan helpen en je zult het waarderen.


0
2017-12-28 22:27



weer een ander gaat hetzelfde probleem aan - form-container op npm


0
2018-03-03 23:52