反应-TypeError:无法读取未定义的属性“长度”

时间:2019-11-11 16:29:21

标签: javascript reactjs

我正在尝试在填充表单时在React中构建一个表单验证系统,就像这样:

Orders.jsx

import { orderFormRules } from './forms/form-rules.js';
import FormErrors from './forms/FormErrors.jsx';

class Orders extends Component {
  constructor (props) {
    super(props);
    this.state = {
      formClient: {
        client: '',
        phone: '',
        email: '',
        select: '',
      },
      clients:[],
      orderFormRules:orderFormRules,
      valid:false
    };
    this.handleSubmitOrder = this.handleSubmitOrder.bind(this);
    this.handleOrderFormChange = this.handleOrderFormChange.bind(this);
  };

validateForm() {
    // define self as this
    const self = this;
    // get form data
    const formClient = this.state.formClient;
    // reset all rules
    self.resetRules()
    if (self.props.formType === 'Order'){
      const formRules = self.state.orderFormRules;
      if (formClient.client.length > 5) formRules[0].valid = true;
      if (this.validateEmail(formClient.email)) formRules[1].valid = true;
      if (formClient.phone.length > 5) formRules[2].valid = true;
      if (formClient.select.length > 5) formRules[3].valid = true;
      self.setState({formClient: formRules})
      if (self.allTrue()) self.setState({valid: true});
    }
  };

allTrue() {
    let formRules = orderFormRules;
    if (this.props.formType === 'Order') {
      formRules = orderFormRules;
    }
    for (const rule of formRules) {
      if (!rule.valid) return false;
    }
    return true;
  };

  resetRules() {
    const orderFormRules = this.state.orderFormRules;
    for (const rule of orderFormRules) {
      rule.valid = false;
    }
    this.setState({orderFormRules: orderFormRules})
    this.setState({valid: false});
  };

  validateEmail(email) {
    // eslint-disable-next-line
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
  };

在处理表单更改时,我要求进行验证,例如:

    handleOrderFormChange(event) {
      const obj = this.state.formClient;
      obj[event.target.name] = event.target.value;
      this.setState({ formClient:obj })
      this.validateForm(); 
   };

以及在渲染调用<FormErrors中:

  render() {

let orderFormRules = this.state.orderFormRules; 
if (this.props.formType === 'Order') {
  orderFormRules = this.state.orderFormRules;
}

return (
  <div>
  <h1 className="title is-1">Register Order</font></h1>
  <FormErrors
        formType={this.props.formType}
        formRules={orderFormRules}
      />
  <div className="Line" /><br/>
   <form onSubmit={ (event) => this.handleSubmitOrder(event) }>
      <div className="field">
         <input
            name="client"
            className="input is-dark is-large"
            type="text"
            placeholder="Client name"
            required
            //value={this.state.formClient.client}
            onChange={this.handleOrderFormChange}
          /> 
      </div>
        <div className="field">
          <input
            name="email"
            className="input is-dark is-large"
            type="email"
            placeholder="Client email"
            required
            //value={this.state.formClient.email}
            onChange={this.handleOrderFormChange}
          />
        </div>
      <div className="field">
        <input
          name="phone"
          className="input is-dark is-large"
          type="text"
          placeholder="Client phone"
          required
          //value={this.state.formClient.phone}
          onChange={this.handleOrderFormChange}
        />
      </div>
      <div className="field">
        <input
          name="select"
          className="input is-dark is-large"
          type="text"
          placeholder="Coffee ordered by client"
          required
          //value={this.state.formClient.select}
          onChange={this.handleOrderFormChange}
        />
      </div>

      <input
        type="submit"
        className="button is-dark is-large is-fullwidth"
        value="Submit"
        //disabled={!this.state.valid}  
      />
      </form>
     </div>
     )
    };
   };

FormErrors.jsx

import React from 'react';

import './FormErrors.css';

const FormErrors = (props) => {
  return (
    <div>
      <ul className="validation-list">
        {
          props.formRules.map((rule) => {
            return <li
              className={rule.valid ? "success" : "error"} key={rule.id}>{rule.name}
            </li>
          })
        }
      </ul>
      <br/>
    </div>
  )
};

export default FormErrors;

form-rules.js

    export const orderFormRules = [
  {
    id: 1,
    field: 'client',
    name: 'Client real name.',
    valid: false
  },
  {
    id: 2,
    field: 'email',
    name: 'Email is required.',
    valid: false
  },
  {
    id: 3,
    field: 'phone',
    name: 'Phone is required.',
    valid: false
  },
  {
    id: 4,
    field: 'select',
    name: 'Coffee is required.',
    valid: false
  }
];

行为

当我使用cookie(它们中的任何一个)填写第一个表单时,根据console.log,它接受该第一项并将其状态更改为“ fine”。然后是在第二次自动填充时中断,或者在我键入该项目时在任何一次中断,都出现以下错误:

TypeError: Cannot read property 'length' of undefined

  56 | if (self.props.formType === 'Order'){
  57 |   const formRules = self.state.orderFormRules;
> 58 |   if (formClient.client.length > 5) formRules[0].valid = true;
     | ^  59 |   if (this.validateEmail(formClient.email)) formRules[1].valid = true;
  60 |   if (formClient.phone.length > 5) formRules[2].valid = true;
  61 |   if (formClient.select.length > 5) formRules[3].valid = true;

完整控制台:

Orders.jsx:58 Uncaught TypeError: Cannot read property 'length' of undefined
    at Orders.validateForm (Orders.jsx:58)
    at Orders.handleOrderFormChange (Orders.jsx:122)
    at HTMLUnknownElement.callCallback (react-dom.development.js:363)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:412)
    at invokeGuardedCallback (react-dom.development.js:466)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:481)
    at executeDispatch (react-dom.development.js:614)
    at executeDispatchesInOrder (react-dom.development.js:639)
    at executeDispatchesAndRelease (react-dom.development.js:744)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:753)
    at Array.forEach (<anonymous>)
    at forEachAccumulated (react-dom.development.js:723)
    at runEventsInBatch (react-dom.development.js:770)
    at runExtractedPluginEventsInBatch (react-dom.development.js:916)
    at handleTopLevel (react-dom.development.js:6171)
    at batchedEventUpdates (react-dom.development.js:2422)
    at dispatchEventForPluginEventSystem (react-dom.development.js:6271)
    at dispatchEvent (react-dom.development.js:6301)
    at unstable_runWithPriority (scheduler.development.js:674)
    at runWithPriority$2 (react-dom.development.js:11834)
    at discreteUpdates$1 (react-dom.development.js:22935)
    at discreteUpdates (react-dom.development.js:2440)
    at dispatchDiscreteEvent (react-dom.development.js:6254)

我想念什么?

2 个答案:

答案 0 :(得分:0)

我只是重构您的Orders类组件,它对我有用

orders.jsx

import React, { Component } from "react";
import { orderFormRules } from "./form-rule";
import FormErrors from "./formErrors";

class Orders extends Component {
  state = {
    formClient: {
      client: "",
      phone: "",
      email: "",
      select: ""
    },
    clients: [],
    orderFormRules: orderFormRules,
    valid: false
  };

  validateForm() {
    // define self as this
    const self = this;
    // get form data
    const formClient = this.state.formClient;
    // reset all rules
    self.resetRules();
    if (self.props.formType === "Order") {
      const formRules = self.state.orderFormRules;
      if (formClient.client.length > 5) formRules[0].valid = true;
      if (this.validateEmail(formClient.email)) formRules[1].valid = true;
      if (formClient.phone.length > 5) formRules[2].valid = true;
      if (formClient.select.length > 5) formRules[3].valid = true;
      self.setState({ formClient: formRules });
      if (self.allTrue()) self.setState({ valid: true });
    }
  }

  handleOrderFormChange = event => {
    const obj = this.state.formClient;
    obj[event.target.name] = event.target.value;
    this.setState({ formClient: obj });
    this.validateForm();
  };

  handleSubmitOrder = event => {
    event.preventDefault();
    console.log(event.target);
  };

  allTrue() {
    let formRules = orderFormRules;
    if (this.props.formType === "Order") {
      formRules = orderFormRules;
    }
    for (const rule of formRules) {
      if (!rule.valid) return false;
    }
    return true;
  }

  resetRules() {
    const orderFormRules = this.state.orderFormRules;
    for (const rule of orderFormRules) {
      rule.valid = false;
    }
    this.setState({ orderFormRules: orderFormRules });
    this.setState({ valid: false });
  }

  validateEmail(email) {
    // eslint-disable-next-line
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
  }

  render() {
    let orderFormRules = this.state.orderFormRules;
    if (this.props.formType === "Order") {
      orderFormRules = this.state.orderFormRules;
    }

    return (
      <div>
        <h1 className="title is-1">Register Order</h1>
        <FormErrors formType={this.props.formType} formRules={orderFormRules} />
        <div className="Line" />
        <br />
        {/* <form onSubmit={event => this.handleSubmitOrder(event)}> */}
        <form onSubmit={this.handleSubmitOrder}>
          <div className="field">
            <input
              name="client"
              className="input is-dark is-large"
              type="text"
              placeholder="Client name"
              required
              //value={this.state.formClient.client}
              onChange={this.handleOrderFormChange}
            />
          </div>
          <div className="field">
            <input
              name="email"
              className="input is-dark is-large"
              type="email"
              placeholder="Client email"
              required
              //value={this.state.formClient.email}
              onChange={this.handleOrderFormChange}
            />
          </div>
          <div className="field">
            <input
              name="phone"
              className="input is-dark is-large"
              type="text"
              placeholder="Client phone"
              required
              //value={this.state.formClient.phone}
              onChange={this.handleOrderFormChange}
            />
          </div>
          <div className="field">
            <input
              name="select"
              className="input is-dark is-large"
              type="text"
              placeholder="Coffee ordered by client"
              required
              //value={this.state.formClient.select}
              onChange={this.handleOrderFormChange}
            />
          </div>

          <input
            type="submit"
            className="button is-dark is-large is-fullwidth"
            value="Submit"
            //disabled={!this.state.valid}
          />
        </form>
      </div>
    );
  }
}
// }

export default Orders;

答案 1 :(得分:0)

validateForm() { const self = this; const formClient = this.state.formClient; self.resetRules() if (self.props.formType === 'Order'){ const formRules = self.state.orderFormRules; if (formClient.client.length > 5) formRules[0].valid = true; if (this.validateEmail(formClient.email)) formRules[1].valid = true; if (formClient.phone.length > 5) formRules[2].valid = true; if (formClient.select.length > 5) formRules[3].valid = true; // comment this out -----> self.setState({formClient: formRules}) if (self.allTrue()) self.setState({valid: true}); } }; 就是问题所在:

def invoke_cloud_function(function_url, payload):
    # Make sure to replace variables with appropriate values
    receiving_function_url = function_url

    # Set up metadata server request
    metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='

    token_request_url = metadata_server_token_url + receiving_function_url
    token_request_headers = {'Metadata-Flavor': 'Google'}

    # Fetch the token
    token_response = requests.get(token_request_url, headers=token_request_headers)
    jwt = token_response.content.decode("utf-8")

    # Provide the token in the request to the receiving function
    receiving_function_headers = {'Authorization': f'bearer {jwt}'}
    function_response = requests.get(receiving_function_url, params=payload, headers=receiving_function_headers)

    return function_response.json()

当我删除该行时,它起作用了。