Вот шаблон формы, которую я пишу с помощью Formik и react-bootstrap. Я нахожу очень странную ошибку: если я инициализирую свое состояние фиктивными данными в конструкторе, оно работает нормально; но если я вызову setState с точно такими же данными в componentDidMount для имитации вызова API, он ужасно сломается.
В частности, я обнаружил, что массив переменной состояния alertVehicles может иметь ненулевую длину, но соответствующая переменная Formik values.alertVehicles может быть пустой. Прямо сейчас форма, как она написана, не отображает флажки. Если я использую alertVehicles вместо values.alertVehicles в своем защитном предложении, то он вылетает с ошибкой Cannot read property 'selected' of undefined.
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, handleChangeEvent, handleSubmit}) => (
<Form onSubmit = {handleSubmit}>
<Form.Label>Name</Form.Label>
<Form.Control
type = "text"
name = "alertRecipient.name"
value = {values.alertRecipient.name}
onChange = {handleChangeEvent}
/>
<Form.Label>Phone number</Form.Label>
<Form.Control
type = "text"
name = "alertRecipient.simNumber"
value = {values.alertRecipient.simNumber}
onChange = {handleChangeEvent}
>
</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 = { handleChangeEvent }
/>
))
}
<Button type = "submit">Save</Button>
</Form>
)
}
/>
</>
)
}
}
export default Alerts;
я не понимаю
componentDidMountvalues.alertVehicles не синхронизировано с alertVehicles.Заранее благодарю за любую помощь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


По какой-то причине это поведение Formik по умолчанию, и вам нужно указать свойство enableReinitialize, чтобы переопределить его:
https://github.com/jaredpalmer/formik/issues/811
@AderemiDayo, у вас есть какие-либо ссылки на его поведение по умолчанию? потому что это работа меня после enableReintialize=true в Formik
На самом деле это имеет смысл. В большинстве случаев вы не хотите стирать то, что пользователь может делать в форме только потому, что состояние изменилось. На самом деле вы, вероятно, захотите, если пользователь еще ничего не коснулся, но не после.
В любом случае они дают вам флаг, чтобы управлять им...
Это поведение по умолчанию настолько ненужно и тратит время