Javascript Formik值不随状态更新

Javascript Formik值不随状态更新,javascript,reactjs,react-bootstrap,formik,Javascript,Reactjs,React Bootstrap,Formik,这是我用Formik和react bootstrap编写的表单模板。我发现了一个非常奇怪的错误:如果我在构造函数中使用虚拟数据初始化我的状态,它就可以正常工作;但是,如果我在componentDidMount中使用完全相同的数据调用setState来模拟API调用,它会崩溃得很厉害 具体来说,我发现状态变量alertVehicles数组的长度可以非零,但相应的Formik值。alertVehicles变量可以为空。现在,所写的表单不会呈现任何复选框。如果我在我的guard子句中使用alertVe

这是我用Formik和react bootstrap编写的表单模板。我发现了一个非常奇怪的错误:如果我在构造函数中使用虚拟数据初始化我的状态,它就可以正常工作;但是,如果我在
componentDidMount
中使用完全相同的数据调用setState来模拟API调用,它会崩溃得很厉害

具体来说,我发现状态变量
alertVehicles
数组的长度可以非零,但相应的Formik
值。alertVehicles
变量可以为空。现在,所写的表单不会呈现任何复选框。如果我在我的guard子句中使用
alertVehicles
而不是
values.alertVehicles
,则它会出现错误
无法读取未定义的属性“selected”

import React, {Component} from 'react';
import Form from 'react-bootstrap/Form';
import { Formik } from 'formik';
import Button from 'react-bootstrap/Button';


class Alerts extends Component {
    constructor(props) {
        super(props);
        this.loadAlertData = this.loadAlertData.bind(this);
        this.state = {
            alertRecipient: {},
            alertId: '',
            alertVehicles: []
        }
    }

    componentDidMount(){
        this.loadAlertData();
    }

    loadAlertData(){
        // this will be an API call eventually, obviously.
        // if this is initialised in the constructor then everything works!
        this.setState( {
            alertRecipient: {
                name: 'Rob',
                simNumber: '0123456789',
            },
            alertId: 1,
            alertVehicles: [
                {id: 1, vrn: 'vehicle A', selected: true },
                {id: 2, vrn: 'vehicle B', selected: false },
                {id: 3, vrn: 'vehicle C', selected: true }
            ]
        })
    }

    render() {
        const { alertRecipient, alertId, alertVehicles } = this.state;
        return (
            <>
                <Formik
                    initialValues={{ alertRecipient, alertId, alertVehicles }}
                    onSubmit={ values => {
                            window.alert(JSON.stringify(values))
                        }
                    }
                    render={({values, handleChange, handleSubmit}) => (
                        <Form onSubmit={handleSubmit}>
                            <Form.Label>Name</Form.Label>
                            <Form.Control
                                type="text"
                                name="alertRecipient.name"
                                value={values.alertRecipient.name}
                                onChange={handleChange}
                            />
                            <Form.Label>Phone number</Form.Label>
                            <Form.Control
                                type="text"
                                name="alertRecipient.simNumber"
                                value={values.alertRecipient.simNumber}
                                onChange={handleChange}
                            >
                            </Form.Control>
                            <Form.Label>Vehicles</Form.Label>
                            {
                                //get an error if we just use alertVehicles.length here??
                                values.alertVehicles.length === 0 ? null : alertVehicles.map((veh, index) => (

                                    <Form.Check type="checkbox"
                                                key={veh.id}
                                                label={veh.vrn}
                                                name={`alertVehicles[${index}].selected`}
                                                checked={values.alertVehicles[index].selected}
                                                onChange={ handleChange }
                                    />
                                ))
                            }
                            <Button type="submit">Save</Button>
                        </Form>
                    )
                    }
                />
            </>
        )
    }

}

export default Alerts;
import React,{Component}来自'React';
从“react引导/表单”导入表单;
从'Formik'导入{Formik};
从“反应引导/按钮”导入按钮;
类警报扩展组件{
建造师(道具){
超级(道具);
this.loadAlertData=this.loadAlertData.bind(this);
此.state={
alertRecipient:{},
警报ID:“”,
警报车辆:[]
}
}
componentDidMount(){
这是loadAlertData();
}
loadAlertData(){
//显然,这最终将是一个API调用。
//如果这是在构造函数中初始化的,那么一切都正常!
此.setState({
收件人:{
姓名:“Rob”,
simNumber:'0123456789',
},
警报ID:1,
警报车辆:[
{id:1,vrn:'vehicle A',selected:true},
{id:2,vrn:'vehicle B',selected:false},
{id:3,vrn:'vehicle C',selected:true}
]
})
}
render(){
const{alertRecipient,alertId,alertVehicles}=this.state;
返回(
{
window.alert(JSON.stringify(值))
}
}
render={({values,handleChange,handleSubmit})=>(
名称
电话号码
车辆
{
//如果只使用alertVehicles.length,则会出现错误??
values.alertVehicles.length==0?空:alertVehicles.map((车辆,索引)=>(
))
}
拯救
)
}
/>
)
}
}
导出默认警报;
我不明白

  • 为什么在构造函数中设置虚拟数据而不是在
    componentDidMount
  • 为什么
    值。alertVehicles
    似乎与
    alertVehicles
    不同步

  • 提前感谢您的帮助。

    出于某种原因,这是Formik的默认行为,您需要提供
    enableReinitialize
    道具来覆盖它:

    这种默认行为是如此不必要和浪费时间