【发布时间】:2021-03-23 22:32:20
【问题描述】:
我有一个带有表单的组件,AddExpense.tsx。表单应该有添加另一个类别的选项。这是一个单独的、解耦的表单,存储在 AddCategory.tsx 组件中。 我需要这个组件以可视方式出现在 AddExpense 表单中,但不幸的是,这似乎破坏了 AddCategory 事件处理程序。如何嵌套这些表单并让它们与单独的 submitHandlers 一起使用?
AddExpense.tsx:
export const AddExpense = (props: AddExpenseProps) => {
const { user } = useAuth()
const [addCategoryIsHidden, setAddCategoryIsHidden] = useState(true)
const [state, setState] = useState({
category: '',
amount: 0,
notes: '',
date: '',
user_id: user.info.user_id
})
const [validated, setValidated] = useState(false)
const { categories } = props
const handleSubmit = async(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
console.log('yo')
const form = e.currentTarget;
if (form.checkValidity() === true) {
await fetch('/api/addExpense', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(state)
}).then(result => {
console.log(result)
if (result.status === 200) {
console.log('success!')
} else {
console.log('error!')
}
})
} else {
e.preventDefault();
e.stopPropagation();
}
setValidated(true);
}
return (
<div className='form-wrapper'>
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<Form.Group controlId='expenseCategory'>
<Form.Label>Category</Form.Label>
<Form.Control
required as='select'
onChange={(e) => setState({...state, category: e.target.value })}
>
{categories.map((category, index) => (
<option key={index} value={category.category_name}>{category.category_name}</option>
))}
</Form.Control>
</Form.Group>
<a
onClick={(e) => setAddCategoryIsHidden(false)}
style={{cursor: 'pointer', color: 'blue', textDecoration: 'underline', textDecorationColor: 'blue'}}>
Add a new category
</a>
<AddCategory hidden={addCategoryIsHidden} type='expenses'/>
<Form.Group controlId='expenseAmount'>
<Form.Label>Amount</Form.Label>
<Form.Control
required
type="number"
step=".01"
onChange={(e) => setState({...state, amount: parseFloat(e.target.value) })}/>
<Form.Control.Feedback type="invalid">
Please provide a valid amount.
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="expenseNotes">
<Form.Label>Notes</Form.Label>
<Form.Control
as="textarea"
rows={3}
placeholder="(optional)"
onChange={(e) => setState({...state, notes: e.target.value})}/>
</Form.Group>
<Form.Group controlId="expenseDate">
<Form.Label>Date</Form.Label>
<Form.Control
required
type="date"
name='date_of_expense'
onChange={(e) => setState({...state, date: e.target.value})}/>
<Form.Control.Feedback type="invalid">
Please select a date.
</Form.Control.Feedback>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
)
}
AddCategory.tsx:
export const AddCategory = ({ type, hidden }: AddCategoryProps) => {
const [newCategory, setNewCategory] = useState<string>()
const { user } = useAuth()
const handleSubmit = async(e: React.FormEvent<HTMLFormElement>) => {
await fetch(`/api/addCategory`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
category_name: newCategory,
user_id: user.info.user_id,
type: type})
})
}
return (
hidden ? null :
<Form onSubmit={handleSubmit}>
<Form.Group controlId='addCategory'>
<Form.Control
required
type="text"
placeholder="new category name"
onChange={(e) => setNewCategory(e.target.value)}>
</Form.Control>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
)
}
【问题讨论】:
标签: reactjs typescript forms