Я создаю базовое c приложение с длинной формой.
Форма управляется с помощью redux и меняет состояние redux на входе с помощью метода onChange
. Вот мой компонент формы:
import React, { Component } from "react";
import { connect } from "react-redux";
import { setCard } from "../../store/actions/card";
import "../../constants/colors.css";
import "./UI.css";
class CardForm extends Component {
constructor(props) {
super(props);
this.state = {
id: props.card.id,
businessName: props.card.businessName,
businessIndustry: props.card.businessIndustry,
businessServices: props.card.businessServices,
businessPhoneNumber: props.card.businessPhoneNumber,
businessEmail: props.card.businessEmail,
};
}
handleImageSelectorClick = () => {};
cardFormInputChangeHandler = async (event) => {
await this.setState({
[event.target.name]: event.target.value,
});
const businessNameValue = this.state.businessName;
const businessIndustryValue = this.state.businessIndustry;
const businessServicesValue = this.state.businessServices;
const businessPhoneNumberValue = this.state.businessPhoneNumber;
const businessEmailValue = this.state.businessEmail;
this.props.setCard(
this.state.id,
businessNameValue,
businessIndustryValue,
businessServicesValue,
businessPhoneNumberValue,
businessEmailValue
);
};
render() {
return (
<div className="primary-light-bg card-form-wrapper">
<div className="card-form-container">
<div
className="primary-color-bg card-form-business-img"
onClick={this.handleImageSelectorClick}
></div>
<input
className="card-form-input"
name="businessName"
placeholder="Business Name"
value={this.state.businessName}
onChange={this.cardFormInputChangeHandler}
/>
<div className="card-form-dropdown-container">
<select
className="card-form-dropdown"
name="businessIndustry"
defaultValue={
this.state.businessIndustry === ""
? "DEFAULT"
: this.state.businessIndustry
}
onChange={this.cardFormInputChangeHandler}
>
<option value="DEFAULT" disabled>
Select a Business Industry
</option>
<option value="Software Development">Software Development</option>
<option value="Clothing and Apparel">Clothing and Apparel</option>
<option value="Health and Beauty">Health and Beauty</option>
</select>
</div>
<textarea
className="card-form-input-large"
name="businessServices"
placeholder="Business Services"
value={this.state.businessServices}
onChange={this.cardFormInputChangeHandler}
/>
<div className="card-form-contact-fields">
<input
id="cardFormInputPhoneNumber"
className="card-form-input-contact"
name="businessPhoneNumber"
placeholder="Phone Number"
value={this.state.businessPhoneNumber}
onChange={this.cardFormInputChangeHandler}
/>
<input
id="cardFormInputEmail"
className="card-form-input-contact"
name="businessEmail"
placeholder="Email"
value={this.state.businessEmail}
onChange={this.cardFormInputChangeHandler}
/>
</div>
<div
className="card-form-button"
onClick={() => this.props.toggleModal()}
>
<span className="primary-color card-form-button-text">
+ Add Social Media
</span>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
card: state.card,
};
};
const mapDispatchToProps = (dispatch) => {
return {
setCard: (
id,
businessName,
businessIndustry,
businessServices,
businessPhoneNumber,
businessEmail
) =>
dispatch(
setCard(
id,
businessName,
businessIndustry,
businessServices,
businessPhoneNumber,
businessEmail
)
),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(CardForm);
Это мой редуктор и действие для моей формы:
cardActions. js
import { IS_LOADING, IS_NOT_LOADING } from "./loader";
export const FETCH_CARD = "FETCH_CARD";
export const SET_CARD = "SET_CARD";
export const fetchCard = () => {
return (dispatch) => {
dispatch({ type: IS_LOADING });
fetch(`http://localhost:4000/cards/1`)
.then((resp) => resp.json())
.then((card) => {
dispatch({ type: SET_CARD, card: card });
localStorage.setItem("card", JSON.stringify(card));
dispatch({ type: IS_NOT_LOADING });
});
};
};
export const setCard = (
id,
businessName,
businessIndustry,
businessServices,
businessPhoneNumber,
businessEmail
) => {
return {
type: SET_CARD,
card: {
id,
businessName,
businessIndustry,
businessServices,
businessPhoneNumber,
businessEmail,
},
};
};
Каждый раз, когда информация о карте извлекается из моего API, я сохраняю объект карты в localStorage
, чтобы получить чистую копию самой последней информации о карте.
cardReducer. js
import { SET_CARD } from "../actions/card";
const initialState = {
id: null,
businessName: "",
businessIndustry: "",
businessServices: "",
businessPhoneNumber: "",
businessEmail: "",
};
const loader = (state = initialState, action) => {
switch (action.type) {
case SET_CARD:
return {
id: action.card.id,
businessName: action.card.businessName,
businessIndustry: action.card.businessIndustry,
businessServices: action.card.businessServices,
businessPhoneNumber: action.card.businessPhoneNumber,
businessEmail: action.card.businessEmail,
};
default:
return state;
}
};
export default loader;
В моем Приложение. js, я сравниваю карту localStorage
с моим текущим состоянием редукции:
componentDidMount() {
window.addEventListener("beforeunload", this.keepOnPage);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.keepOnPage);
}
keepOnPage = (event) => {
const localStorageCard = JSON.parse(localStorage.getItem("card"));
if (this.props.card === localStorageCard) {
return;
} else {
let message;
event.returnValue = message;
return message;
}
};
{ ... }
const mapStateToProps = (state) => {
return {
card: state.card,
};
};
export default connect(mapStateToProps)(App);
Моя единственная проблема в том, что когда я перехожу к другому маршруту, я обновляю / перезагружаю / закрываю окно , он показывает "Обновить сайт?" запросить, не меняя состояние редукции.
Есть ли лучший способ сделать это?