Reactjs 如何解决react引导typeahead的此错误
我有一个名为ProductCard的子组件,它从名为CreateNewSales的父组件获取道具。onChange函数有两个参数,在父函数中定义。如果我在ProductCard中调用该函数,我会继续得到typeahead的这个错误,尽管除了数量输入之外的其他输入似乎都正常工作。代码如下: 这是产品卡:Reactjs 如何解决react引导typeahead的此错误,reactjs,input,react-bootstrap,typeahead,react-bootstrap-typeahead,Reactjs,Input,React Bootstrap,Typeahead,React Bootstrap Typeahead,我有一个名为ProductCard的子组件,它从名为CreateNewSales的父组件获取道具。onChange函数有两个参数,在父函数中定义。如果我在ProductCard中调用该函数,我会继续得到typeahead的这个错误,尽管除了数量输入之外的其他输入似乎都正常工作。代码如下: 这是产品卡: import React, { useState, Fragment } from 'react'; import { FormGroup, Label, Input, Col} from 're
import React, { useState, Fragment } from 'react';
import { FormGroup, Label, Input, Col} from 'reactstrap';
import { Typeahead } from 'react-bootstrap-typeahead';
import PropTypes from 'prop-types';
import {PlusSquare, MinusSquare} from 'react-feather'
const plusSquare = <PlusSquare/>
const minusSquare = <MinusSquare/>
const ProductCard = (props) => {
console.log(props)
const ProductOptions = [{id:1,name: "Clothes"}, {id:2,name:"Services"}, {id:3,name:"Shows"}, {id:4,name: "Peace"}] //dummy date //res_data.payload.data.product
// const [singleSelections, setSingleSelections] = useState([]);
// from quantityIncrement.js
const [count, setCount] = useState(1)
const decrement = () => {
if(count === 1){
setCount(count)
} else{
setCount(count-1)
}
};
const increment = () => {
setCount(count+1)
};
return(
<Fragment>
<FormGroup>
<Label>Product Name</Label>
<Typeahead
id="basic-typeahead"
labelKey="name"
onChange={(e) => props.handleChange(e, props.index)}
// onInputChange={props.setProductName}
options={ProductOptions}
name={ProductOptions}
selected={props.value.productName}
style={{backgroundColor:"#d5deee"}}
value={props.value.productName}
/>
</FormGroup>
<FormGroup>
<div className="form-row">
<Col>
<Label for="quantity">Quantity</Label>
<div style={{display: "flex"}}>
<Input value={count} id="quantity" name="quantity" onChange={e=> setCount(e.target.value)} style={{backgroundColor: "#d5deee"}} />
<div style={{display:"flex", marginTop:"5px"}}><span><i style={{ width: 15, fontSize: 10, padding: 11, color: '#848b97' }} onClick={increment}>{plusSquare}</i></span><span><i style={{ width: 15, fontSize: 12, color: '#848b97' }} onClick={decrement}>{minusSquare}</i></span></div>
</div>
</Col>
<Col>
<Label for="discount">Discount</Label>
<Input type="text" id="discount" onChange = {(e) => props.handleChange(e, props.index)} value={props.value.discount} name="discount" style={{backgroundColor:"#d5deee"}} />
</Col>
</div>
</FormGroup>
<FormGroup>
<div className="form-row">
<Col>
<Label for="price">Price</Label>
<Input type="text" id="price" onChange={(e) => props.handleChange(e, props.index)} value={props.value.price} name="price" style={{backgroundColor:"#d5deee"}} />
</Col>
<Col>
<Label for="amountPaid">Amount Paid</Label>
<Input type="text" id="amountPaid" onChange={(e) => props.handleChange(e, props.index)} value={props.value.amountPaid} name="amountPaid" style={{backgroundColor:"#d5deee"}} />
</Col>
</div>
</FormGroup>
</Fragment>
)
}
ProductCard.propTypes = {
handleChange: PropTypes.func.isRequired,
value: PropTypes.object.isRequired,
// onClickQuantity: PropTypes.func.isRequired
}
export default ProductCard
import React,{useState,Fragment}来自“React”;
从“reactstrap”导入{FormGroup,Label,Input,Col};
从'react bootstrap Typeahead'导入{Typeahead};
从“道具类型”导入道具类型;
从“react feather”导入{PlusSquare,MinusSquare}
常数加平方=
常数平方=
const ProductCard=(道具)=>{
控制台日志(道具)
const ProductOptions=[{id:1,name:“costs”},{id:2,name:“Services”},{id:3,name:“Shows”},{id:4,name:“Peace”}]//虚拟日期//res_data.payload.data.product
//常量[singleSelections,setSingleSelections]=useState([]);
//来自quantityIncrement.js
const[count,setCount]=useState(1)
常数减量=()=>{
如果(计数==1){
设置计数(计数)
}否则{
设置计数(计数-1)
}
};
常量增量=()=>{
设置计数(计数+1)
};
返回(
品名
props.handleChange(e,props.index)}
//onInputChange={props.setProductName}
选项={ProductOptions}
名称={ProductOptions}
所选={props.value.productName}
风格={{backgroundColor:{d5deee}
value={props.value.productName}
/>
量
setCount(e.target.value)}style={{{backgroundColor:“#d5deee”}}/>
{plusSquare}{minusSquare}
优惠
props.handleChange(e,props.index)}value={props.value.discount}name=“discount”style={{{{backgroundColor:“#d5deee”}}/>
价格
props.handleChange(e,props.index)}value={props.value.price}name=“price”style={{{{backgroundColor:“#d5deee”}}/>
已付金额
props.handleChange(e,props.index)}value={props.value.amountpayed}name=“amountpayed”style={{{backgroundColor:“#d5deee”}/>
)
}
ProductCard.propTypes={
handleChange:PropTypes.func.isRequired,
值:PropTypes.object.isRequired,
//onClickQuantity:PropTypes.func.isRequired
}
导出默认产品卡
这是CreateNewSale:
import React, { Fragment, useState } from 'react';
import {Form, FormGroup, Label, Input, Card, Col, Row, CardBody, Button, ButtonGroup, Table} from 'reactstrap';
import {toast} from 'react-toastify';
import { Typeahead } from 'react-bootstrap-typeahead';
import { withRouter} from 'react-router';
// import {useHistory} from 'react-router-dom';
import {connect} from 'react-redux';
import {validateCreateNewSaleForm, responseErrorParser} from "../../components/authentication/validator"
// productCard.js
import ProductCard from '../../components/sales/ProductCard'
import {Trash2} from 'react-feather'
const trash2 = <Trash2/>
const CreateNewSale = (props) => {
const [, setIsCreatingNewSale] = useState(false)
// const [singleSelections, setSingleSelections] = useState([]);
// from the productCard.js
const [newProductValues, setNewProductValues] = useState([{
productName: [],
discount: "",
price: "",
amountPaid: "",
quantity: "1",
}]);
// const [newProductName, setNewProductName] = useState([{
// newProductNames: [],
// newCustomerName: []
// }])
// const handleInputChange = (event) => {
// setNewProductName({
// ...newProductName,
// [event.target.name]: event.target.value
// });
// }
const [customerName, setCustomerName] = useState([])
const [date, setDate] = useState('')
const [dueDate, setDueDate] = useState('')
const [vat, setVat] = useState('')
// const [visible, setVisible] = useState(false)
const handleChange = (event, index) => {
console.log( event )
const values = [...newProductValues];
values[index][event.target.name] = event.target.value
console.log('=======================>', values)
setNewProductValues(values);
// setNewProductValues({
// ...newProductValues,
// [event.target.name]: event.target.value
// });
}
const handleAddFields = (e) => {
setNewProductValues([...newProductValues, {discount:"", price: "",
amountPaid: "",
quantity: "1",
productName:[]
}])
}
const handleRemoveFields = (index) => {
const values = [...newProductValues];
values.splice(index, 1);
setNewProductValues(values);
}
const customerOptions = [{id: 1, name: "Olalekan"}, {id: 2, name:"Michael"}, {id: 3,name:"Emeka"}, {id:4,name: "Glory"}] //dummy data //res_data.payload.data.customer
const fields = {
customer_name: { default: '', message: 'Please enter an already created customer name' },
product_name: { default: '', message: 'Please enter an already created customer name' },
quantity: { default: '', message: 'Please select a quantity' },
discount: { default: '', message: 'Please enter the discount given' },
price: { default: '', message: 'Please select the price given' },
amount_paid: { default: '', message: 'Please enter the amount paid by the customer' },
date: { default: '', message: 'Please enter date' },
due_date: { default: '', message: 'Please enter due date given' },
vat: { default: '', message: 'Please enter the vat' },
}
const handleCreateNewSale = async (e) => {
e.preventDefault()
setIsCreatingNewSale(true);
const responsePayload = {
customer_name: newProductValues.newCustomerName, //customerName
product_name: newProductValues.newproductNames,
quantity: newProductValues.quantity,
discount: newProductValues.discount,
price: newProductValues.price,
amount_paid: newProductValues.amountPaid,
date: date,
due_date: dueDate,
vat: vat
}
const errors = validateCreateNewSaleForm(responsePayload, fields)
if (errors.isErrors) {
setIsCreatingNewSale(false)
setTimeout(() => {
errors.errors.forEach(e => toast.error(e.message))
}, 400);
} else {
const response = await props.CreateNewSale(responsePayload)
if (response.status) {
const newSale = response.payload.data.id
localStorage.setItem('__grm__act__biz__', newSale.toString())
// props.history.push(`/business/${newSale}.toString/sales/invoice`, {previousLocation: props.location.pathname})
} else {
setIsCreatingNewSale(false)
const payload = response.payload
const errs = responseErrorParser(payload.data)
setTimeout(() => {
errs.forEach(e => toast.error(e.message))
}, 400);
}
}
}
return(
<Fragment>
<div style={{display:"flex", fontFamily:"'Poppins', sans-serif"}}>
<div className="col-lg-10" style={{margin: "0 auto", maxWidth:"500px", width:"100%"}}>
<Form>
<Card>
<CardBody>
<FormGroup>
<Label>Customer Name</Label>
<Typeahead
id="basic-typeahead"
labelKey="name"
onChange={setCustomerName}
options={customerOptions}
selected={customerName}
value={customerName}
name="customerName"
style={{backgroundColor:"#d5deee"}}
/>
</FormGroup>
</CardBody>
</Card>
{ newProductValues.map((newProductValue, index) => (
<div key={index}>
<Card >
<CardBody>
<Col style={{textAlign: "right"}}>
<i onClick={() => handleRemoveFields()} >{trash2}</i>
</Col>
<ProductCard index={index} handleChange={handleChange} value={newProductValue} />
</CardBody>
</Card>
</div>
))}
<Row>
<Col>
<p onClick={() => handleAddFields()} style={{marginLeft:"20px"}}> <span style={{fontSize:"18px"}}>+</span> Add another product</p>
</Col>
</Row>
<Row>
<Col>
<p onClick={() => handleAddFields()} style={{marginLeft:"20px"}}> <span style={{fontSize:"18px"}}>+</span> Add another product</p>
</Col>
</Row>
<Card>
<CardBody>
<FormGroup>
<div className="form-row">
<Col>
<Label for="date">Date</Label>
<Input className="form-control digits" type="date" defaultValue="2018-01-01" value={date} onChange={e => setDate(e.target.value)} id="date" name="date" style={{backgroundColor:"#d5deee"}} />
</Col>
<Col>
<Label for="dueDate">Due Date</Label>
<Input className="form-control digits" type="date" defaultValue="2018-01-01" value={dueDate} onChange={e => setDueDate(e.target.value)} id="dueDate" name="dueDate" style={{backgroundColor:"#d5deee"}} />
</Col>
</div>
</FormGroup>
<FormGroup>
<div className="form-row">
<Col>
<Label for="vat">VAT %</Label>
<Input type="text" id="vat" value={vat} onChange={e => setVat(e.target.value)} style={{backgroundColor:"#d5deee"}} />
</Col>
</div>
</FormGroup>
<div style={{margin:"0 auto", textAlign:"center"}}>
<p style={{fontSize:"12px"}}>Only click cleared if this sales have been paid in full</p>
<Row>
<Col>
<ButtonGroup>
<Button outline color="primary" type="button">Cleared</Button>
<Button outline color="primary" type="button">Not Cleared</Button>
</ButtonGroup>
</Col>
</Row>
</div>
<Row className="m-t-50">
<Col lg={`6`}>
<Button outline color="primary" size="lg" style={{maxWidth:"200px", width:"100%"}}>SAVE</Button>
</Col>
<Col lg={`6`}>
<Button color="primary" size="lg" onClick={e => handleCreateNewSale(e)} style={{maxWidth:"200px", width:"100%"}}>CREATE</Button>
</Col>
</Row>
</CardBody>
</Card>
</Form>
</div>
<div className="col-lg-2" style={{backgroundColor:"#eaf6fd", position:"fixed", right:0, height:"100%",}}>
<Card className="m-t-50">
<CardBody>
<div>You have added <span>0</span> products</div>
</CardBody>
</Card>
<div className="table-responsive">
<Table borderless>
<tbody>
<tr>
<td className="bd-t-none">Sub Total</td>
<td>000 000 000</td>
</tr>
<tr style={{fontWeight:"bold"}}>
<td className="bd-t-none">Total</td>
<td>000 000 000</td>
</tr>
</tbody>
</Table>
</div>
</div>
</div>
</Fragment>
)
}
const mapStateToProps = (state) => ({
requestingCreateNewSale: state.isRequestingCreateNewSale,
});
const actions = {
CreateNewSale: CreateNewSale
};
export default connect(mapStateToProps, actions)(withRouter(CreateNewSale))
import React,{Fragment,useState}来自'React';
从“reactstrap”导入{Form,FormGroup,Label,Input,Card,Col,Row,CardBody,Button,ButtonGroup,Table};
从'react toastify'导入{toast};
从'react bootstrap Typeahead'导入{Typeahead};
从“react router”导入{withRouter};
//从'react router dom'导入{useHistory};
从'react redux'导入{connect};
从“./../components/authentication/validator”导入{validateCreateNewSaleForm,responseErrorParser}
//productCard.js
从“../../components/sales/ProductCard”导入ProductCard
从“react feather”导入{Trash2}
常量垃圾2=
const CreateNewSale=(道具)=>{
const[,setIsCreatingNewSale]=使用状态(false)
//常量[singleSelections,setSingleSelections]=useState([]);
//从productCard.js
常量[newProductValues,setNewProductValues]=useState([{
产品名称:[],
折扣:“,
价格:“,
已付金额:“,
数量:“1”,
}]);
//常量[newProductName,setNewProductName]=useState([{
//新产品名称:[],
//新客户名称:[]
// }])
//常量handleInputChange=(事件)=>{
//setNewProductName({
//…newProductName,
//[event.target.name]:event.target.value
// });
// }
const[customerName,setCustomerName]=useState([])
const[date,setDate]=useState(“”)
const[dueDate,setDueDate]=useState(“”)
const[vat,setVat]=useState(“”)
//const[visible,setVisible]=useState(false)
常量handleChange=(事件、索引)=>{
console.log(事件)
常量值=[…newProductValues];
值[index][event.target.name]=event.target.value
console.log('=========================>',值)
setNewProductValues(值);
//SetNewProductValue({
//…新产品价值观,
//[event.target.name]:event.target.value
// });
}
const handleaddields=(e)=>{
setNewProductValues([…newProductValues,{折扣:,价格:,
已付金额:“,
数量:“1”,
产品名称:[]
}])
}
常量handleRemoveFields=(索引)=>{
常量值=[…newProductValues];
拼接值(索引1);
setNewProductValues(值);
}
const customerOptions=[{id:1,name:“Olalekan”},{id:2,name:“Michael”},{id:3,name:“Emeka”},{id:4,name:“glori”}]//虚拟数据//res_data.payload.data.customer
常量字段={
客户名称:{默认值:'',消息:'请输入已创建的客户名称'},
产品名称:{默认值:'',消息:'请输入已创建的客户名称'},
数量:{默认值:'',消息:'请选择一个数量'},
折扣:{默认值:'',消息:'请输入给定的折扣'},
价格:{默认值:'',消息:'请选择给定的价格'},
支付金额:{默认值:'',消息:'请输入客户支付的金额',
日期:{默认值:'',消息:'请输入日期'},
到期日:{默认值:'',消息:'请输入给定的到期日'},
增值税:{默认值:'',消息:'请输入增值税'},
}
const handleCreateNewSale=async(e)=>{
e、 预防默认值()
setIsCreatingNewSale(真);
const responsePayload={
客户名称:newProductValues.newCustomerName,//customerName
产品名称:newProductValues.newproductNames,
数量:新台币
TypeError: Cannot read property 'name' of undefined
handleChange
src/pages/sales/CreateNewSales.js:54
51 | const handleChange = (event, index) => {
52 | console.log( event )
53 | const values = [...newProductValues];
> 54 | values[index][event.target.name] = event.target.value
| ^ 55 | console.log('=======================>', values)
56 | setNewProductValues(values);
57 | // setNewProductValues({
View compiled
onChange
src/components/sales/ProductCard.jsx:40
37 | <Typeahead
38 | id="basic-typeahead"
39 | labelKey="name"
> 40 | onChange={(e) => props.handleChange(e, props.index)}
| ^ 41 | // onInputChange={props.setProductName}
42 | options={ProductOptions}
43 | name={ProductOptions}