Состояние не работает должным образом после перехода на предыдущую страницу в браузере в React Redux
Я занимаюсь разработкой веб-приложения React + Redux. У меня проблема с государственным управлением.
У меня есть компонент под названием EditEventComponent
со следующим определением.
class EditEventComponent extends React.Component{
constructor(props)
{
super(props)
//curator/event/{event_id}/details
this.fetchEvent = this.fetchEvent.bind(this);
}
componentDidMount()
{
this.fetchEvent();
}
fetchEvent()
{
this.props.startFetchingEvent();
let path = "curator/event/" + this.props.match.params.id + "/details";
getHttpClient().get(path)
.then((response) => {
this.props.completeFetchingEvent(response.data);
})
.catch((error) => {
this.props.errorFetchingEvent();
});
}
render()
{
let props = this.props;
return (<EventFormComponent {...props} />)
}
}
function mapStateToProps(state)
{
return {
submittingForm : state.editEvent.submittingForm,
formErrors : state.editEvent.formErrors,
event: state.editEvent.event,
};
}
function matchDispatchToProps(dispatch)
{
return bindActionCreators({
startFetchingEvent: EditEventActions.startFetchingEvent,
completeFetchingEvent : EditEventActions.completeFetchingEvent,
errorFetchingEvent: EditEventActions.errorFetchingEvent,
startFormSubmission: EditEventActions.startFormSubmission,
completeFormSubmission : EditEventActions.completeFormSubmission,
errorFormSubmission: EditEventActions.errorFormSubmission,
changeInputField : EditEventActions.changeInputfield
}, dispatch);
}
const enhance = compose(withWidth(), withStyles(themeStyles, { withTheme: true }), connect(mapStateToProps, matchDispatchToProps))
export default enhance(EditEventComponent);
Как вы можете видеть, он загружает событие асинхронно с сервера. Затем передайте значение события в EventFormComponent.
Это определение EventComponent.
class EventFormComponent extends React.Component{
constructor(props)
{
super(props);
this.submitCreateEventForm = this.submitCreateEventForm.bind(this);
this.onInputValueChange = this.onInputValueChange.bind(this);
this.getServerFormatDateTime = this.getServerFormatDateTime.bind(this);
this.onCoverPhotoFileValueChange = this.onCoverPhotoFileValueChange.bind(this);
this.validateForm = this.validateForm.bind(this);
this.sendUpdateEventRequest = this.sendUpdateEventRequest.bind(this);
this.renderEventInputField = this.renderEventInputField.bind(this);
this.state = {
startdatetime: null ,
enddatetime: null ,
coverPhotoFile: null,
name: "",
location: "",
description: "",
latitude: "",
longitude: "",
organizers: "",
attendees: ""
}
this.isEditing = this.props.event == null;
}
setStartDateTime = (dateTime) => this.setState({ startdatetime: dateTime })
setEndDateTime = (dateTime) => this.setState({ enddatetime: dateTime })
onInputValueChange(e)
{
alert(this.isEditing)
switch(e.target.name)
{
case "name":
this.setState({ name: e.target.value })
break;
case "location":
this.setState({ location: e.target.value })
break;
case "description":
this.setState({ description: e.target.value })
break;
case "latitude":
this.setState({ latitude: e.target.value })
break;
case "longitude":
this.setState({ longitude: e.target.value })
break;
case "organizers":
this.setState({ organizers: e.target.value })
break;
case "attendees":
this.setState({ attendees: e.target.value })
break;
}
if(this.isEditing)
{
this.props.changeInputField({ field: e.target.name, value: e.target.value });
}
}
submitCreateEventForm(e)
{
e.preventDefault();
if(this.validateForm())
{
this.sendUpdateEventRequest();
}
}
sendUpdateEventRequest()
{
let startDateTime = this.getServerFormatDateTime(String(this.state.startdatetime));
let endDateTime = this.getServerFormatDateTime(String(this.state.enddatetime));
let formData = new FormData();
formData.append("cover_photo_file", this.state.coverPhotoFile);
formData.append("name", this.state.name);
formData.append("location", this.state.location);
formData.append("latitude", this.state.latitude);
formData.append("longitude", this.state.longitude);
formData.append("description", this.state.description);
formData.append("attendee_emails", this.state.attendees);
formData.append("organizer_emails", this.state.organizers);
formData.append('start_date',startDateTime.date);
formData.append('start_time', startDateTime.time);
formData.append('end_date', endDateTime.date);
formData.append("end_time", endDateTime.time);
formData.append('is_csv', true);
let path = "";
if(this.isEditing)
{
formData.append('id', this.props.event.id);
path = "event/post";
}
else
{
path = "event/update";
}
this.props.startFormSubmission();
getHttpClient("multipart/form-data")
.post("event/post", formData)
.then((response) => {
if(response.data.success)
{
this.props.completeFormSubmission();
this.props.history.push("/events");
}
else
{
this.props.errorFormSubmission(response.data.errors);
}
})
.catch((error) => {
this.props.errorFormSubmission([ "Internal error thrown." ])
})
}
validateForm()
{
if(this.state.name == null || this.state.name.trim()=="")
{
this.props.errorFormSubmission([ "Name is required" ]);
return false;
}
return true;
}
onCoverPhotoFileValueChange(e)
{
this.setState({ coverPhotoFile: e.target.files[0] });
}
getServerFormatDateTime(dateTime)
{
if(dateTime!==null && dateTime!=="")
{
let segs = dateTime.split(" ");
let date = segs[1] + "/" + segs[2] + "/" + segs[3];
let time = segs[4];
return { date: date, time: time }
}
else
{
return { date: null, time: null };
}
}
renderEventInputField(fieldName)
{
if(this.isEditing && this.props.event)
{
if(this.props.event[fieldName])
{
return this.props.event[fieldName];
}
else
{
return '';
}
}
else
{
return "";
}
}
render()
{
let formLoadingView = null;
if(this.props.submittingForm)
{
formLoadingView = <div>Processing request....</div>
}
return (
<MuiThemeProvider>
<div className={scss['page-container']}>
<Grid
spacing={16}
container>
<Grid item md={12}>
<Card>
<CardContent>
<form onSubmit={this.submitCreateEventForm}>
{this.props.formErrors.map((item, index)=> {
return <div key={index}>{item}</div>
})}
<div>
<label>Cover photo</label>
<br />
<input type="file" onChange={this.onCoverPhotoFileValueChange} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="name"
label="Name"
value={this.props.event && this.props.event.name? this.props.event.name: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="location"
label="Location"
value={this.props.event && this.props.event.location? this.props.event.location: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="latitude"
label="Latitude"
value={this.props.event && this.props.event.latitude? this.props.event.latitude: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="longitude"
label="Longitude"
value={this.props.event && this.props.event.longitude? this.props.event.longitude: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="attendees"
label="Attendees (Emails)"
value={this.props.event && this.props.event.attendee_emails? this.props.event.attendee_emails: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="organizers"
label="Organizers (Emails)"
value={this.props.event && this.props.event.organizer_emails? this.props.event.organizer_emails: ""} />
</div>
<div>
<TextField
onChange={this.onInputValueChange}
className={scss['form-control']}
name="description"
label="Description"
value={this.props.event && this.props.event.description? this.props.event.description: ""} />
</div>
<div>
<div className={scss['form-control']}>
<DateTimePicker
fullWidth
format='MM/DD/YYYY hh:mm A'
hintText="Start date & time"
onChange={this.setStartDateTime}
value={this.props.event && this.props.event.start_date_time? this.props.event.start_date_time: ""}
DatePicker={DatePickerDialog}
TimePicker={TimePickerDialog}
/>
</div>
</div>
<div>
<div className={scss['form-control']}>
<DateTimePicker
fullWidth
format='MM/DD/YYYY hh:mm A'
hintText="End date & time"
onChange={this.setEndDateTime}
value={this.props.event && this.props.event.end_date_time? this.props.event.end_date_time: ""}
DatePicker={DatePickerDialog}
TimePicker={TimePickerDialog}
/>
</div>
</div>
<div>
</div>
<div>
{formLoadingView}
<Grid>
<Button disabled={this.props.submittingForm} type="submit" color="primary" variant="raised">Save</Button>
</Grid>
</div>
</form>
</CardContent>
</Card>
</Grid>
</Grid>
</div>
</MuiThemeProvider>
)
}
}
export default EventFormComponent;
Обратите внимание на свойство this.isEditing в конструкторе.
Теперь то, что я делаю, это страница, которая отображает список событий, который использует EventListComponent. С этой страницы, если пользователь щелкает виджет события, он перенаправляется на страницу редактирования (EditEventComponent). Я запускаю приложение, затем нажимаю на виджет событий, который перенаправляет на страницу редактирования.
Свойство this.isEditing также становится истинным, так как событие не является нулевым. Затем я возвращаюсь на предыдущую страницу (EventListComponent), щелкая предыдущую кнопку в браузере. Затем я снова выбираю виджет событий для редактирования. Затем, когда я нажимаю, страница редактирования отображается во второй раз, поле isEditing больше не является истинным событием, если данные события загружены.
Событие не является нулевым. Но свойство isEditing имеет значение false. Я не могу придумать решение. Я тоже не знаю почему. Я думаю, что это происходит, когда я нажимаю кнопку "вернуться" в браузере и снова выбираю элемент для редактирования, который перенаправляет пользователя на страницу редактирования назад. Что не так с моим кодом?