Javascript 不带按钮提交反应表单

Javascript 不带按钮提交反应表单,javascript,reactjs,Javascript,Reactjs,尝试使用React中的select按钮处理窗体。选择按钮用于电子商务产品详细信息页面的不同产品变体。基本上,如何让组件在用户将大小/颜色更改为较小(或API具有的任何产品变体)时自动处理表单,因此在我发布时,它在请求中具有变体 理论上,我可以只按一个提交按钮,但他/她每次从小型变为中型时都必须重新提交 import React, { Fragment } from 'react' import axios from 'axios' import { connect } from "react-r

尝试使用React中的select按钮处理窗体。选择按钮用于电子商务产品详细信息页面的不同产品变体。基本上,如何让组件在用户将大小/颜色更改为较小(或API具有的任何产品变体)时自动处理表单,因此在我发布时,它在请求中具有变体

理论上,我可以只按一个提交按钮,但他/她每次从小型变为中型时都必须重新提交

import React, { Fragment } from 'react'
import axios from 'axios'
import { connect } from "react-redux";
import { withRouter } from 'react-router-dom'
import { productDetailURL, addToCartURL } from '../constants'
import { fetchCart } from "../store/actions/cart";
import { authAxios } from '../utils'


class ProductDetail extends React.Component {

    state = {
        loading: false,
        error: null,
        formData: {},
        data: []
      };

    handleChange = (e) => {
      const { formData } = this.state
      const updatedFormData = {
        ...formData,
        [e.target.name]: e.target.value
      }
      this.setState({formData: updatedFormData})
    }

    handleFormatData = formData => {
      // convert {colour: 1, size: 2} to [1,2] - they're all variations
      return Object.keys(formData).map(key => {
        return formData[key];
      });
    };


    componentDidMount() {
    const {match: { params }} = this.props
    axios
      .get(productDetailURL(params.productID))
      .then(res => {
        this.setState({ data: res.data, loading: false });
      })
      .catch(err => {
        this.setState({ error: err, loading: false });
      });
    }

    handleAddToCart = slug => {
        this.setState({ loading: true });
        const { formData } = this.state
        const variations = this.handleFormatData(formData)
        console.log(variations)
        authAxios
          .post(addToCartURL, { slug, variations })
          .then(res => {
            this.setState({ loading: false });
          })
          .catch(err => {
            this.setState({ error: err, loading: false });
          });
      };

    render() {
        console.log(this.state)
        const { data, error, loading, formData } = this.state;
        const  item  = data
        return (
            <div>
            <div class="container">
            {error && (
            <div class="alert alert-danger" role="alert">
            {JSON.stringify(error) }
            </div>
            )}
            {loading && (
            <div class="spinner-border" role="status">
            <span class="sr-only">Loading...</span>
            </div>
            )}
          <div class="card">
          <div class="row no-gutters">
            <aside class="col-md-6">
        <article class="gallery-wrap">
        <div class="img-big-wrap">
          <div> <a href="#"><img src="/images/items/12.jpg"></img></a></div>
        </div>
        <div class="thumbs-wrap">
          <a href="#" class="item-thumb"> <img src="/images/items/12.jpg"></img></a>
          <a href="#" class="item-thumb"> <img src="/images/items/12-1.jpg"></img></a>
          <a href="#" class="item-thumb"> <img src="/images/items/12-2.jpg"></img></a>
        </div>
        </article> 
            </aside>
            <main class="col-md-6 border-left">
        <article class="content-body">

        <h2 class="title">{item.title}</h2>

<div class="rating-wrap my-3">
    <ul class="rating-stars">
        <li  class="stars-active">
            <i class="fa fa-star"></i> <i class="fa fa-star"></i>
            <i class="fa fa-star"></i> <i class="fa fa-star"></i>
            <i class="fa fa-star"></i>
        </li>
        <li>
            <i class="fa fa-star"></i> <i class="fa fa-star"></i>
            <i class="fa fa-star"></i> <i class="fa fa-star"></i>
            <i class="fa fa-star"></i>
        </li>
    </ul>
    <small class="label-rating text-muted">132 reviews</small>
    <small class="label-rating text-success"> <i class="fa fa-clipboard-check"></i> 154 orders </small>
</div>

<div class="mb-3">
    <var class="price h4">${item.price}</var>
</div>

<p>{item.description}</p>

<hr></hr>
    <div class="form-row">
        <div class="form-group col-md flex-grow-0">
            <label>Quantity</label>
            <div class="input-group mb-3 input-spinner">
              <div class="input-group-prepend">
                <button class="btn btn-light" type="button" id="button-plus"> + </button>
              </div>
              <input type="text" class="form-control" value="1"></input>
              <div class="input-group-append">
                <button class="btn btn-light" type="button" id="button-minus"> − </button>
              </div>
            </div>
        </div>
        <div class="form-group col-md flex-grow-0">
    <form onSubmit={this.handleFormatData}>
    {data.variations &&
                data.variations.map(v => {
                  const name = v.name.toLowerCase()
                  return (
                    <Fragment key={v.id}>
                      {/* <div class="card"> */}
                      <div class="card-body">
                      <div class="form-inline d-inline-flex ml-luto">
                      <label as="h3">{v.name}</label>
                      <select className="ml-2 form-control" name={name}  onChange={this.handleChange}>

                        {v.item_variations.map(iv => {
                          return (
                            <option
                            onChange={this.handleChange}
                            key={iv.id} 
                            value={iv.id}
                            >
                              {iv.value}
                            </option>
                          );
                        })}

                      </select>
                      </div>
                      </div>
                      {/* </div> */}
                    </Fragment>
                  );
                })}
              </form>
              </div>
            </div>
            <a href="#" class="btn  btn-primary"> Buy now </a>
            <a onClick={() => this.handleAddToCart(item.slug)} class="btn  btn-outline-primary"> <span class="text">Add to cart</span> <i class="fas fa-shopping-cart"></i>  </a>
          </article>
              </main>
            </div>
          </div>
            </div>
            </div>
        )
    }
}


const mapDispatchToProps = dispatch => {
    return {
      refreshCart: () => dispatch(fetchCart())
    };
  };

  export default withRouter(
    connect(
      null,
      mapDispatchToProps
    )(ProductDetail)
  );
import React,{Fragment}来自“React”
从“axios”导入axios
从“react redux”导入{connect};
从“react router dom”导入{withRouter}
从“../constants”导入{productDetailURL,addToCartURL}
从“./store/actions/cart”导入{fetchCart};
从“../utils”导入{authAxios}
类ProductDetail扩展了React.Component{
状态={
加载:false,
错误:null,
formData:{},
数据:[]
};
handleChange=(e)=>{
const{formData}=this.state
常量updatedFormData={
…表格数据,
[e.target.name]:e.target.value
}
this.setState({formData:updatedFormData})
}
handleFormatData=formData=>{
//将{color:1,size:2}转换为[1,2]-它们都是变体
返回Object.keys(formData.map)(key=>{
返回formData[键];
});
};
componentDidMount(){
常量{match:{params}}=this.props
axios
.get(productDetailURL(params.productID))
。然后(res=>{
this.setState({data:res.data,load:false});
})
.catch(错误=>{
this.setState({error:err,load:false});
});
}
HandLeadToCart=slug=>{
this.setState({loading:true});
const{formData}=this.state
常量变量=this.handleFormatData(formData)
console.log(变体)
奥塔克索斯
.post(addToCartURL,{slug,variances})
。然后(res=>{
this.setState({loading:false});
})
.catch(错误=>{
this.setState({error:err,load:false});
});
};
render(){
console.log(this.state)
const{data,error,loading,formData}=this.state;
常量项=数据
返回(
{错误&&(
{JSON.stringify(错误)}
)}
{加载&&(
加载。。。
)}
this.handleAddToCart(item.slug)}class=“btn btn outline primary”>添加到购物车
)
}
}
const mapDispatchToProps=调度=>{
返回{
refreshCart:()=>分派(fetchCart())
};
};
使用路由器导出默认值(
连接(
无效的
mapDispatchToProps
)(产品详情)
);

欢迎来到StackOverflow!因此,从您的问题来看,您似乎希望在您的本地州存储一些用户偏好(产品变体),并希望在提交表单之前可以使用这些偏好(产品变体)?看起来你是对的!我只看到一个bug-您在
选择标记和
选项上都有
this.handleChange
。您只需要
选择
:)上的onChange处理程序,我这样做了,并将add-to-cart移动到表单内部。工作!非常感谢。完美的我还要说的是,您不必只使用
标记来提交表单。您也可以在onClick上执行相同的操作。您可以通过任何方式单独存储表单状态,也可以使用提交处理程序。