gpt4 book ai didi

javascript - 在 componentWillReceiveProps 中触发 redux 表单提交

转载 作者:行者123 更新时间:2023-12-03 00:56:57 25 4
gpt4 key购买 nike

当用户提交表单时,我会检查某个字段的值是否已更改。如果有,我将显示一个确认模式。如果用户在模态中单击"is",模态组件会在 redux 中将“dismissedSubTypeChangeWarning”属性设置为 true。

在 componentWillReceiveProps 内部,我监听此 prop 的任何更改。如果它的值为 true,我想触发表单的提交。我按照 https://redux-form.com/6.5.0/examples/remotesubmit/ 上的说明进行操作进行配置。

调度调用永远不会触发,因为在控制台中我看到“检测到解雇”,然后什么也没有。我希望在“检测到解雇”之后看到“submitForm 方法”。

我将代码(如下)压缩为最基本的版本来显示问题。当我运行代码时,我在控制台中没有看到任何错误。

我找到了使用 refs 的解决方案(请参阅注释行),但伪造点击似乎不是一个好的做法。

class ChangeEditForm extends React.Component {
componentWillReceiveProps (nextProps) {
if (nextProps.dismissedSubTypeChangeWarning) {
console.log('detected dismiss')
this.props.toggleDismissedSubTypeChangeWarning()
this.props.dispatch(submit('changeEdit'))
// this.refs.submit.click()
}
}

render () {
<form onSubmit={this.props.handleSubmit(this.props.submitForm)}>
<button type='submit' ref='submit'>Save</button>
</form>
}
}

const handlers = {
submitForm: props => (formValues) => {
console.log('submitForm method')
if ((formValues.subtype !== props.initialValues.subtype) && !props.dismissedSubTypeChangeWarning) {
console.log('show warning')
props.toggleSubTypeChangeConfirmModal()
} else {
console.log('submitting form')
}
}
}

export function mapStateToProps (state, props) {
return {
dismissedSubTypeChangeWarning: state.ui.dismissedSubTypeChangeWarning
}
}

export default compose(
pure,
reduxForm({
form: 'changeEdit',
onSubmit: handlers.submitForm
}),
connect(mapStateToProps, null),
withRouter,
withHandlers(handlers)
)(ChangeEditForm)

最佳答案

我仍然认为您的表单提交过于复杂化。

正如评论中提到的,表单提交一次,值检查一次,如果值不同,则会生成弹出窗口,在弹出窗口中确认更新值,否则取消将关闭模式并保持表单不变。

通过创建HOC,我们可以控制模式和表单,而无需在弹出确认时重新提交表单。

工作示例:https://codesandbox.io/s/lxv9o1nxzl

container/ChangeNameHOC.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { reset } from "redux-form";
import { updateUser } from "../actions";
import { Values } from "redux-form-website-template";
import ChangeNameForm from "./ChangeNameForm";
import ShowModal from "../components/ShowModal";
import CurrentStore from "../containers/CurrentStore";

class ChangeNameHOC extends Component {
state = {
modalIsOpen: false,
formProps: {}
};

openModal = () => this.setState({ modalIsOpen: true });

closeModal = () => this.setState({ modalIsOpen: false });

validateFormValues = formProps => {
const { firstName, lastName } = this.props;
const nextFirstName = formProps.firstName;
const nextLastName = formProps.lastName;

if (firstName !== nextFirstName || lastName !== nextLastName) {
this.setState({ modalIsOpen: true, formProps });
}
};

handleSubmit = () => {
this.setState({ modalIsOpen: false }, () => {
this.props.updateUser(this.state.formProps);
this.props.reset("ChangeNameForm");
});
};

render = () => (
<div style={{ padding: "0px 20px" }}>
<ShowModal
{...this.state}
{...this.props}
afterOpenModal={this.afterOpenModal}
openModal={this.openModal}
closeModal={this.closeModal}
handleSubmit={this.handleSubmit}
/>
<ChangeNameForm validateFormValues={this.validateFormValues} />
<CurrentStore />
<Values form="ChangeNameForm" />
</div>
);
}

export default connect(
state => ({
firstName: state.user.firstName,
lastName: state.user.lastName
}),
{ updateUser, reset }
)(ChangeNameHOC);

containers/ChangeNameForm.js

import React from "react";
import { Field, reduxForm } from "redux-form";
import RenderField from "../components/RenderField";

const isRequired = value => (!value ? "Required" : undefined);

const ChangeNameForm = ({
handleSubmit,
reset,
submitting,
validateFormValues
}) => (
<form onSubmit={handleSubmit(validateFormValues)}>
<Field
className="uk-input"
label="First Name"
name="firstName"
component={RenderField}
type="text"
placeholder="First Name"
validate={[isRequired]}
/>
<Field
className="uk-input"
label="Last Name"
name="lastName"
component={RenderField}
type="text"
placeholder="Last Name"
validate={[isRequired]}
/>
<button
className="uk-button uk-button-primary"
type="submit"
disabled={submitting}
style={{ marginBottom: 20 }}
>
Submit
</button>
<div style={{ float: "right" }}>
<button
className="uk-button uk-button-danger"
type="button"
disabled={submitting}
onClick={reset}
style={{ marginBottom: 20 }}
>
Reset
</button>
</div>
</form>
);

export default reduxForm({
form: "ChangeNameForm"
})(ChangeNameForm);

组件/ShowModal.js

import React, { PureComponent } from "react";
import Modal from "react-modal";

const customStyles = {
content: {
minWidth: "400px",
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)"
}
};

Modal.setAppElement("#root");

export default class ShowModal extends PureComponent {
showChange = (name, prevName, nextName) => (
<div>
{name}: <strong>{prevName}</strong> to <strong>{nextName}</strong>
</div>
);

render = () => {
const { firstName, lastName } = this.props;
const { firstName: nextFirstName } = this.props.formProps;
const { lastName: nextLastName } = this.props.formProps;

return (
<div>
<Modal
isOpen={this.props.modalIsOpen}
onAfterOpen={this.props.afterOpenModal}
onRequestClose={this.props.closeModal}
style={customStyles}
contentLabel="Are you sure?"
>
<h3>Are you sure you want to update?</h3>
<div style={{ marginBottom: 20 }}>
{firstName !== nextFirstName
? this.showChange("FirstName", firstName, nextFirstName)
: null}
{lastName !== nextLastName
? this.showChange("LastName", lastName, nextLastName)
: null}
</div>
<button
style={{ float: "left" }}
className="uk-button uk-button-primary"
onClick={this.props.handleSubmit}
>
confirm
</button>
<button
style={{ float: "right" }}
className="uk-button uk-button-danger"
onClick={this.props.closeModal}
>
cancel
</button>
</Modal>
</div>
);
};
}

关于javascript - 在 componentWillReceiveProps 中触发 redux 表单提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52786464/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com