javascript - 更改 useEffect 中的状态不会更改界面

标签 javascript reactjs react-hooks

我在 React 中使用 useState 和 useEffect 钩子(Hook)来渲染表单。但是当我使用 useEffect Hook 更新表单时。该表单不会重新呈现。

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 Hook 中,api 调用更新表单,因此重新渲染仓库类型选择输入,但选择输入不会重新渲染。可能是什么原因造成的。

最佳答案

您还需要复制嵌套值:

{
        warehouseType: {
            elementType: 'select',
            elementConfig: {
                options: [
                    { value: '4', displayValue: 'Showroom' }
                ]
            },
            value: '1',
            validation: {},
            valid: true
        },

...
const updatedForm = { ...form };
                updatedForm.warehouseType.options = updatedWarehouseTypes;
                setForm(updatedForm);

您还错过了其中的elementConfigupdatedForm.warehouseTypes.elementConfig.options

但是复制嵌套值仍然是一个好主意。

const updatedForm = {
                    ...form, 
                    warehouseType: {...form.warehouseType, 
                          elementConfig: {...form.elementConfig,
                               options:updatedWarehouseTypes 
                    }}};

关于javascript - 更改 useEffect 中的状态不会更改界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57889612/

相关文章:

reactjs - 为什么 ReactJS 中 DOM 不随着状态变化而更新?

javascript - reselect如何影响组件的渲染

javascript - ReactJS类型错误: undefined is not a function (near '...this.state.data.map...' )

javascript - 需要没有 Browserify、Webpack 或 Babel 的 reactjs 模块

javascript - 如何将 Heroes 数组更改为 res 数组?我正在使用 react useState Hook 。这在以前的项目中有效,但在这里不起作用

javascript - 简单的reactjs组件出现意外的 token 错误

javascript - jquery 和 javascript 可以共存于一个文件中吗?

javascript - 是否可以从字符串模板文字中推断泛型类型

javascript - 部署 firebase 文件时,index.html 未更新

javascript - map 不返回正确的对象数组