我在 react 中使用 useState 和 useEffect 钩子来渲染表单。但是当我使用 useEffect 钩子更新表单时。窗体不会重新呈现。
import React, { useState, useEffect } from 'react';
import { makeStyles } from "@material-ui/core/styles";
import GridItem from "components/Grid/GridItem.js";
import GridContainer from "components/Grid/GridContainer.js";
import Card from "components/Card/Card.js";
import CardHeader from "components/Card/CardHeader.js";
import CardBody from "components/Card/CardBody.js";
import Input from "components/UI/Input/Input";
import Button from "components/CustomButtons/Button.js";
import styles from "styles/styles";
import falconAPI from "falcon-api";
const useStyles = makeStyles(styles);
export default function AddWarehouse(props) {
const classes = useStyles();
// State management hooks
const [form, setForm] = useState({
warehouseType: {
elementType: 'select',
elementConfig: {
options: [
{ value: '4', displayValue: 'Showroom' }
]
},
value: '1',
validation: {},
valid: true
},
territory: {
elementType: 'select',
elementConfig: {
options: [
{ value: '1', displayValue: 'Kandy' },
{ value: '2', displayValue: 'Jaffna' },
{ value: '3', displayValue: 'Colombo' },
{ value: '4', displayValue: 'Galle' }
]
},
value: '1',
validation: {},
valid: true
},
name: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Name'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
},
address: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Address'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
},
telephone: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Telephone'
},
value: '',
validation: {
required: true,
},
valid: false,
touched: false
},
});
// Life cycle hooks
useEffect(() => {
falconAPI.post('/warehouse/type/all')
.then(response => {
const warehouseTypes = response.data.message;
const updatedWarehouseTypes = []
warehouseTypes.map(warehouseType => {
updatedWarehouseTypes.push({
value: warehouseType.id,
displayValue: warehouseType.name
});
})
const updatedForm = { ...form };
updatedForm.warehouseType.options = updatedWarehouseTypes;
setForm(updatedForm);
})
.catch(error => {
});
}, []);
const inputChangedHandler = (e) => {
}
const submitFormHandler = (e) => {
console.log(form);
}
const formElementsArray = [];
for (let key in form){
formElementsArray.push({
id: key,
config: form[key]
})
}
return (
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<Card>
<CardHeader color="success">
<h4 className={classes.cardTitleWhite}>{props.title}</h4>
</CardHeader>
<CardBody>
{formElementsArray.map(formElement => (
<Input
key={formElement.id}
elementType={formElement.config.elementType}
elementConfig={formElement.config.elementConfig}
value={formElement.config.value}
invalid={!formElement.config.valid}
shouldValidate={formElement.config.validation}
touched={formElement.config.touched}
changed={(event) => inputChangedHandler(event, formElement.id)} />
))}
<Button onClick={submitFormHandler}>Add Model</Button>
</CardBody>
</Card>
</GridItem>
</GridContainer>
);
}
在 useEffect 挂钩中,api 调用更新表单,因此重新呈现仓库类型选择输入,但选择输入不会重新呈现。这可能是什么原因。
您还需要复制嵌套值:
{
warehouseType: {
elementType: 'select',
elementConfig: {
options: [
{ value: '4', displayValue: 'Showroom' }
]
},
value: '1',
validation: {},
valid: true
},
...
const updatedForm = { ...form };
updatedForm.warehouseType.options = updatedWarehouseTypes;
setForm(updatedForm);
你也错过了那里elementConfig
。updatedForm.warehouseTypes.elementConfig.options
但是复制嵌套值仍然是一个好主意。
const updatedForm = {
...form,
warehouseType: {...form.warehouseType,
elementConfig: {...form.elementConfig,
options:updatedWarehouseTypes
}}};