Как правило, я хочу изменить состояние пользовательского интерфейса в компоненте, когда глобальное состояние было изменено в Redux-Store.
Мой сценарий выглядит следующим образом:
- Показатьмодальная форма, когда пользователь нажимает кнопку «Добавить учащегося»
- Показывать «Сохранение ...», когда пользователь нажимает кнопку «Сохранить»
- Если возникает ошибка, диалоговое окно должно оставаться открытым ипоказать ошибку
- Если вставка в порядке, диалог должен быть закрыт автоматически
Я набрал первые 3 очка, но я застрял в 4-й точке и не знаю, как реализовать функцию Close
после успешной вставки.
Я хотел бы запускать следующий пример кода всякий раз, когда isSubmitting / error была измененав Redux-магазине.Но я не знаю, где его запустить.Я пытался поместить его в метод render (), но он не работает, и я больше не мог открыть диалоговое окно.
Код для проверки и закрытия модального
if (isSubmitting === false && error === null)
this.setState({ add: false });
Я не хочу поднимать это состояние пользовательского интерфейса (например, IsModalOpen - bool) в хранилище Global Redux.Я уже поместил состояние пользовательского интерфейса isSubmitting в Redux, и я не хочу продолжать добавлять состояния пользовательского интерфейса в Redux Store.
Не могли бы вы предложить мне, как я могу закрыть диалоговое окно после успешной вставки?
Я поместил образец кода в CodeSandbox, и он здесь
Редуктор
const initialState = {
isSubmitting: false,
error: null,
student: null
};
function rootReducer(state = initialState, action) {
switch (action.type) {
case "STUDENT_ADD_BEGIN": {
return {
...state,
isSubmitting: true
};
}
case "STUDENT_ADD_SUCCESS": {
return {
...state,
student: action.payload,
error: null,
isSubmitting: false
};
}
case "STUDENT_ADD_ERROR": {
return {
...state,
isSubmitting: false,
error: action.error,
student: null
};
}
default:
return state;
}
}
export default rootReducer;
Контейнер /Страница
class addStudentPage extends Component {
constructor(props) {
super(props);
this.state = {
dataList: [],
add: false,
edit: false,
dataItem: {}
};
}
getInitialState() {
return {
id: "",
name: "TTCG"
};
}
componentDidMount() {
this.setState({
dataItem: this.getInitialState()
});
}
toggleAdd = () => {
this.setState(prevState => ({
add: !prevState.add
}));
};
showAddNew = () => {
this.toggleAdd();
this.setState({
dataItem: this.getInitialState()
});
};
updateItemState = event => {
const field = event.target.name;
const value = event.target.value;
let item = this.state.dataItem;
item[field] = value;
return this.setState({ dataItem: item });
};
handleAddNew = () => {
let item = this.state.dataItem;
item["id"] = uuid.v4();
console.info(item);
this.props.addStudentAction(item);
};
render() {
const { isSubmitting, error } = this.props;
return (
<Container>
<h1>Students</h1>
<Button onClick={this.showAddNew} color="link">
Add New Student
</Button>
{this.state.add && (
<AddStudent
toggle={this.toggleAdd}
modal={this.state.add}
item={this.state.dataItem}
onChange={this.updateItemState}
onAddNew={this.handleAddNew}
isSubmitting={isSubmitting}
error={error}
/>
)}
{this.props.student && (
<h6>You have added a new student named: {this.props.student.name}</h6>
)}
</Container>
);
}
}
const mapStateToProps = state => {
return {
isSubmitting: state.studentReducer.isSubmitting,
error: state.studentReducer.error,
student: state.studentReducer.student
};
};
const mapDispatchToProps = {
addStudentAction: item => addStudentAction(item)
};
Модальная форма
export default class StudentAdd extends Component {
render() {
const {
modal,
toggle,
item,
onChange,
onAddNew,
isSubmitting,
error
} = this.props;
return (
<Modal isOpen={modal} toggle={toggle} centered>
<ModalHeader toggle={toggle}>Add New Student</ModalHeader>
<ModalBody>
{error && <Alert color="danger">{error}</Alert>}
<Form>
<FormGroup>
<Label for="Name">Name</Label>
<Input
type="text"
name="name"
id="Name"
value={item.name}
onChange={onChange}
/>{" "}
type 'error' to simulate error
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={onAddNew} disabled={isSubmitting}>
{isSubmitting ? "Saving..." : "Save"}
</Button>{" "}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
);
}
}
ОБНОВЛЕНИЯ
Это может быть достигнуто с помощью componentDidUpdate
метод жизненного цикла, как показано ниже: пожалуйста, будьте внимательны, чтобы правильно проверить реквизиты и состояния перед выводом состояния.
componentDidUpdate(prevProps) {
const { isSubmitting, error } = this.props;
if (isSubmitting !== prevProps.isSubmitting || error !== prevProps.error) {
if (isSubmitting === false && error === null)
this.setState({ add: false });
}
}
Или вы можете использовать getDerivedStateFromProps
метод жизненного цикла для пересчета реквизитов.Но мне было трудно пользоваться чем componentDidUpdate
.