如何让我输入验证和禁用/启用我的提交按钮取决于ReactJS形式的状态

问题描述 投票:0回答:1

我使用NPM验证,并试图验证输入的信息,然后更改取决于验证提交地址按钮的状态。我的方式有它设置现在我打字和文本显示在控制台中,但不是在UI。我不知道我有什么错。该按钮将不会更改为“Enabled”无论是。

以下是部分:

import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input, Button } from 'reactstrap';
import './StripeCheckoutForm.css';
import validator from 'validator';

const cardElement = {
  base: {
    color: '#32325d',
    width: '50%',
    lineHeight: '30px',
    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
    fontSmoothing: 'antialiased',
    fontSize: '18px',
    '::placeholder': {
      color: '#aab7c4'
    }
  },
  invalid: {
    color: '#fa755a',
    iconColor: '#fa755a'
  }
};

const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';

// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
  const res = await fetch(FIREBASE_FUNCTION, {
      method: 'POST',
      body: JSON.stringify({
          token,
          charge: {
              amount,
              currency,
          },
      }),
  });
  const data = await res.json();
  data.body = JSON.parse(data.body);
  return data;
}

class CheckoutForm extends Component {
  constructor(props) {
    super(props);
    this.submit = this.submit.bind(this);
  }

  state = {
    paymentComplete: false,
    firstName: '',
    lastName: '',
    address: '',
    city: '',
    prefecture: '',
    zipCode: '',
    email: '',
    submitDisabled: true
  }

  inputChangeHandler = (event, name) => {
    console.log('inputChange', name, event.target.value)
    event.preventDefault()
    this.setState({
      name: event.target.value
    }, console.log(this.state.submitDisabled), function(){ this.canSubmit() })
  }

  canSubmit = () => {
    console.log("canSubmit")
    const { firstName, lastName, address, city, prefecture,zipCode, email} = this.state
    if (validator.isAlpha(firstName) 
    && validator.isAlpha(lastName) 
    && address > 0
    && validator.isAlpha(city)
    && validator.isAlpha(prefecture)
    && zipCode > 0
    && validator.isEmail(email)) {
      this.setState({submitDisabled: false})
    } else {
      this.setState({submitDisabled: true})
    }
  }

  clearCartHandler = () => {
    console.log('clearCartHandler');
    this.props.onClearCart()
  }

  // User clicked submit
  async submit(ev) {
    console.log("clicked!")
    const {token} = await this.props.stripe.createToken({name: "Name"});
    const total = getTotal(this.props.cartItems);
    const amount = total; // TODO: replace with form data
    const currency = 'USD';
    const response = await charge(token, amount, currency);

    if (response.statusCode === 200) {
      this.setState({paymentComplete: true});
      console.log('200!!',response);
      this.clearCartHandler();

    } else {
      alert("wrong credit information")
      console.error("error: ", response);
    }
  }

  render() {

    if (this.state.complete) {
      return (
        <div>
          <h1 className="purchase-complete">Purchase Complete</h1>
          <Link to='/'>
            <button>Continue Shopping</button>
          </Link>
        </div>
      );
    }

    return ( 
      <div className="checkout-wrapper"> 
      <Container className="App">
        <h2 className='text-center'>Let's Checkout</h2>
          <Form className="form">
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="first name"
                  name={"first name"}
                  value={this.state.firstName}
                  id="exampleEmail"
                  placeholder="first name"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="last name"
                  name="last name"
                  value={this.state.lastName}
                  id="exampleEmail"
                  placeholder="last name"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="address"
                  name="address"
                  value={this.state.adress}
                  id="exampleEmail"
                  placeholder="address"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="city"
                  name="city"
                  value={this.state.city}
                  id="exampleEmail"
                  placeholder="city"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="prefecture"
                  name="prefecture"
                  value={this.state.prefecture}
                  id="exampleEmail"
                  placeholder="prefecture"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="zipcode"
                  name="zipcode"
                  value={this.state.zipCode}
                  id="exampleEmail"
                  placeholder="zipcode"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  onChange= {this.inputChangeHandler}
                  type="email"
                  name="email"
                  value={this.state.email}
                  id="exampleEmail"
                  placeholder="[email protected]"
                />
              </FormGroup>
            </Col>
            <Button className="save-address-button" disabled={this.state.submitDisabled}>Submit Address</Button>
            <div className="card-element">
            <CardElement style={cardElement}/>
            </div>
          </Form>
        <button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
      </Container>
      </div> 
    );
  }
}

const mapStateToProps = state => {
  return {
    cartItems: state.shoppingCart.cartItems
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onClearCart: () => dispatch(clearCart())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm));
reactjs reactstrap
1个回答
0
投票

我认为错误是与this.setState的回调函数的滥用。

在你inputChangeHandler方法,您通过三个参数this.setState(),但是,this.setState()希望你顶多只传递两个参数,以第二个参数是回调函数。

既然你通过回调函数作为第三个参数,this.setState()会自动忽略它,所以你的验证方法不会被调用。

另一个问题是有关的inputChangeHandler名称参数,该inputChangeHandler将只接收事件的对象,而不是名字。为了访问输入元素的name属性,则需要通过event.target.name访问它

为了解决这个问题,你可以改变输入更改处理到

inputChangeHandler = event => {
    const { name, value } = event.target;
    console.log('inputChange', event.target.name, event.target.value)

    // notice the square bracket, this means we use the computed variable as 
    // the object key, instead of using the string 'name' as object key
    // also the name attribute in your Input element must match your state's key
    // use name='lastName' instead of name='last name' as your state's key is lastName
    this.setState({
      [name]: value
    }, this.canSubmit) // changing this line
}

如果你想保持你的console.log(this.state.submitDisabled),您可以将您的验证方法中添加。

canSubmit = () => {
    console.log("canSubmit", this.state.submitDisabled) // add it here
    const { firstName, lastName, address, city, prefecture, zipCode, email} = this.state
    if (validator.isAlpha(firstName) 
    && validator.isAlpha(lastName) 
    && address > 0
    && validator.isAlpha(city)
    && validator.isAlpha(prefecture)
    && zipCode > 0
    && validator.isEmail(email)) {
      this.setState({submitDisabled: false})
    } else {
      this.setState({submitDisabled: true})
    }
}

在渲染的方法,我想你的意思

if (this.state.paymentComplete)

代替

if (this.state.complete)

此外,在底部的按钮,你硬编码残疾人属性值

<button
    className="checkout-button"
    disabled={false}
    onClick={this.submit}
>
    Submit
</button>

也许你的意思

<button
    className="checkout-button"
    disabled={this.state.submitDisabled}
    onClick={this.submit}
>
    Submit
</button>

作为一个侧面说明,input元素的类型属性应该是“文”,“数字”,“复选框”,等等。相反,像“姓”或“县”一些随机文本

© www.soinside.com 2019 - 2024. All rights reserved.