ReactJs - 单击按钮时添加一个组件
ReactJs - Add a component when click button
我有一个找不到解决办法的困境。我想导入许多产品,但它们可能属于同一类别,所以当我单击“+”时,显示会添加类似图片的行
我在互联网上看到了很多教程并按照它们进行了操作,但它们都失败了。我不知道该怎么做。请帮我!非常感谢
state = {
listItems: [],
userInput: this.need,
}
need = {
category: "",
name: "",
quantity: ""
}
handleChange = (event) => {
const target = event.target;
const value = target.value;
const name = target.name;
let userInput = { ...this.state.userInput };
userInput[name] = value;
this.setState({ userInput });
}
submitHandler = e => {
e.preventDefault()
this.setState({
listItems: [...this.state.listItems, this.state.userInput],
})
}
<Form>
<Form.Group id="need">
<Row>
<Col md="3">
<label>Category</label>
<select name="category" className="form-control" onChange={this.handleChange}>
<option value="1">Water</option>
<option value="2">Food</option>
</select>
</Col>
<Col md="4">
<label>Name</label>
<Input
name="name"
className="form-control-alternative"
onChange={this.handleChange}
type="text"
/>
</Col>
<Col md="4">
<label>Quantity</label>
<Input
name="quantity"
className="form-control-alternative"
type="text"
onChange={this.handleChange}
/>
</Col>
<Col>
<i style={{ marginTop: 45 }} onClick={submitHandler} >Add more</i>
</Col>
</Row>
</Form.Group>
</Form>
对于这种形式,我更喜欢使用formik而不是this.setState
。
解决方案 1. this.setState
我会这样设计状态
this.state = {
form: [
{
category: "",
name: "",
quantity: 0,
},
],
};
以及添加更多项目的方法,编辑它们的内容
handleAdd = () => {
this.setState({
form: [
...this.state.form,
{
category: "",
name: "",
quantity: 0,
},
]
});
};
handleEditFieldOfItem = (event, itemIndex, fieldName) => {
const value = event.target.value;
this.setState({
form: this.state.form.map((item, index) => {
if (index === itemIndex) {
return { ...item, [fieldName]: value };
}
return item;
})
});
};
我会将这些项目呈现如下:
render() {
return (
<div>
{this.state.form.map((item, index) => {
return (
<div key={index}>
<div>
<select value={item.category} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'category'); }}>
<option value="water">Water</option>
<option value="food">Food</option>
</select>
</div>
<div>
<input type="text" value={item.name} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'name'); }} />
</div>
<div>
<input type="text" value={item.quantity} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'quantity'); }} />
</div>
</div>
);
})}
<button onClick={this.handleAdd}>Add</button>
</div>
);
}
解决方案 2. 使用 Formik(带有 FieldArray
组件)
Formik
具有验证、处理嵌套值的能力,...
您应该先查看 Formik documentation。
import { Formik, Field, FieldArray } from "formik";
// ...
<Formik
initialValues={{
form: [
{
category: "",
name: "",
quantity: 0
}
]
}}
onSubmit={(values, helpers) => {
//
}}
>
{(formikProps) => {
const { values, handleSubmit } = formikProps;
return (
<>
<FieldArray name="form">
{(arrayHelpers) => {
return (
<div>
{values.form.map((item, index) => {
return (
<div key={index}>
<Field as="select" name={`form.${index}.category`}>
<option value="water">Water</option>
<option value="food">Food</option>
</Field>
<Field name={`form.${index}.name`} />
<Field name={`form.${index}.quantity`} />
</div>
);
})}
<div>
<button onClick={() => arrayHelpers.push({ category: '', name: '', quantity: 0 })}>Add</button>
</div>
</div>
)}}
</FieldArray>
<button type="submit">Submit</button>
</>
);
}}
</Formik>
我有一个找不到解决办法的困境。我想导入许多产品,但它们可能属于同一类别,所以当我单击“+”时,显示会添加类似图片的行
state = {
listItems: [],
userInput: this.need,
}
need = {
category: "",
name: "",
quantity: ""
}
handleChange = (event) => {
const target = event.target;
const value = target.value;
const name = target.name;
let userInput = { ...this.state.userInput };
userInput[name] = value;
this.setState({ userInput });
}
submitHandler = e => {
e.preventDefault()
this.setState({
listItems: [...this.state.listItems, this.state.userInput],
})
}
<Form>
<Form.Group id="need">
<Row>
<Col md="3">
<label>Category</label>
<select name="category" className="form-control" onChange={this.handleChange}>
<option value="1">Water</option>
<option value="2">Food</option>
</select>
</Col>
<Col md="4">
<label>Name</label>
<Input
name="name"
className="form-control-alternative"
onChange={this.handleChange}
type="text"
/>
</Col>
<Col md="4">
<label>Quantity</label>
<Input
name="quantity"
className="form-control-alternative"
type="text"
onChange={this.handleChange}
/>
</Col>
<Col>
<i style={{ marginTop: 45 }} onClick={submitHandler} >Add more</i>
</Col>
</Row>
</Form.Group>
</Form>
对于这种形式,我更喜欢使用formik而不是this.setState
。
解决方案 1. this.setState
我会这样设计状态
this.state = {
form: [
{
category: "",
name: "",
quantity: 0,
},
],
};
以及添加更多项目的方法,编辑它们的内容
handleAdd = () => {
this.setState({
form: [
...this.state.form,
{
category: "",
name: "",
quantity: 0,
},
]
});
};
handleEditFieldOfItem = (event, itemIndex, fieldName) => {
const value = event.target.value;
this.setState({
form: this.state.form.map((item, index) => {
if (index === itemIndex) {
return { ...item, [fieldName]: value };
}
return item;
})
});
};
我会将这些项目呈现如下:
render() {
return (
<div>
{this.state.form.map((item, index) => {
return (
<div key={index}>
<div>
<select value={item.category} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'category'); }}>
<option value="water">Water</option>
<option value="food">Food</option>
</select>
</div>
<div>
<input type="text" value={item.name} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'name'); }} />
</div>
<div>
<input type="text" value={item.quantity} onChange={(event) => { this.handleEditFieldOfItem(event, index, 'quantity'); }} />
</div>
</div>
);
})}
<button onClick={this.handleAdd}>Add</button>
</div>
);
}
解决方案 2. 使用 Formik(带有 FieldArray
组件)
Formik
具有验证、处理嵌套值的能力,...
您应该先查看 Formik documentation。
import { Formik, Field, FieldArray } from "formik";
// ...
<Formik
initialValues={{
form: [
{
category: "",
name: "",
quantity: 0
}
]
}}
onSubmit={(values, helpers) => {
//
}}
>
{(formikProps) => {
const { values, handleSubmit } = formikProps;
return (
<>
<FieldArray name="form">
{(arrayHelpers) => {
return (
<div>
{values.form.map((item, index) => {
return (
<div key={index}>
<Field as="select" name={`form.${index}.category`}>
<option value="water">Water</option>
<option value="food">Food</option>
</Field>
<Field name={`form.${index}.name`} />
<Field name={`form.${index}.quantity`} />
</div>
);
})}
<div>
<button onClick={() => arrayHelpers.push({ category: '', name: '', quantity: 0 })}>Add</button>
</div>
</div>
)}}
</FieldArray>
<button type="submit">Submit</button>
</>
);
}}
</Formik>