我有一个奇怪的场景,在我的 redux 开发工具中,我可以看到 redux 状态已更新,但该值并未反映在与之连接的组件中。
所以我有一个像 CreateEnvironment 这样的组件
export interface StateProps {
environment: EnvironmentStep;
selectProduct: SelectProductStep;
eula: EULAStep;
license: LicenseStep;
infrastructure: InfrastructureStep;
network: NetworkStep;
certificate: CertificateStep;
products: any;
}
export interface DispatchProps {
onFormValuesUpdate: (key: string, value: any) => void;
}
type Props = StateProps & DispatchProps;
interface State {
dashboard: boolean;
}
class CreateEnvironment extends Component<Props, State> {
private page: RefObject<any>;
constructor(props: Props) {
super(props);
this.state = { dashboard: false };
this.page = React.createRef();
}
public render() {
console.log("Hi"); //tslint:disable-line
if (this.state.dashboard) {
return <Redirect to="/dashboard" />;
}
const {
environment,
eula,
selectProduct,
infrastructure,
network,
license,
certificate,
onFormValuesUpdate
} = this.props;
return (
<Fragment>
<h2>Create Environment</h2>
<div style={{ height: '100%', paddingBottom: '30px' }}>
<WorkFlow
orientation="vertical"
onNext={this.onNext}
onFinish={this.onFinish}
>
<WorkFlowPage pageTitle="Environment">
<Environment
environment={environment}
onUpdate={onFormValuesUpdate}
ref={this.page}
/>
</WorkFlowPage>
<WorkFlowPage pageTitle="Products & Solutions">
<SelectProduct
ref={this.page}
selectProduct={selectProduct}
onUpdate={onFormValuesUpdate}
/>
</WorkFlowPage>
<WorkFlowPage
pageNavTitle="EULA"
pageTitle="End User License Agreement Details"
>
<Eula eula={eula} ref={this.page} onUpdate={onFormValuesUpdate} />
</WorkFlowPage>
<WorkFlowPage pageTitle="License">
<License
license={license}
ref={this.page}
onUpdate={onFormValuesUpdate}
/>
</WorkFlowPage>
<WorkFlowPage pageTitle="Infrastructure">
<Infrastructure
infrastructure={infrastructure}
ref={this.page}
onUpdate={onFormValuesUpdate}
/>
</WorkFlowPage>
<WorkFlowPage pageTitle="Network">
<Network
network={network}
ref={this.page}
onUpdate={onFormValuesUpdate}
/>
</WorkFlowPage>
<WorkFlowPage pageTitle="Certificate">
<Certificate
certificate={certificate}
ref={this.page}
onUpdate={onFormValuesUpdate}
/>
</WorkFlowPage>
<WorkFlowPage pageTitle="Products">I am products step</WorkFlowPage>
<WorkFlowPage pageTitle="Summary">I am summary step</WorkFlowPage>
<WorkFlowButton role="previous">Back</WorkFlowButton>
<WorkFlowButton role="next">Next</WorkFlowButton>
<WorkFlowButton role="finish">Finish</WorkFlowButton>
</WorkFlow>
</div>
</Fragment>
);
}
private onNext = () => {
if (this.page.current) {
this.page.current.handleSubmit();
}
}
private onFinish = () => {
this.setState({
dashboard: true
});
}
}
export default CreateEnvironment;
对应的容器如下所示:
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import {
CreateEnvironmentAction,
updateEnvironmentWorkflow
} from '../actions/CreateEnvironment';
import {
CreateEnvironment,
DispatchProps,
StateProps
} from '../components/create-environment';
import { StoreState } from '../types';
export const mapStateToProps = ({
createEnvironment
}: StoreState): StateProps => ({
...createEnvironment
});
export const mapDispatchToProps = (
dispatch: Dispatch<CreateEnvironmentAction>
): DispatchProps => ({
onFormValuesUpdate: (key: string, values: any) => {
dispatch(updateEnvironmentWorkflow(key, values));
}
});
export default connect<StateProps, DispatchProps>(
mapStateToProps,
mapDispatchToProps
)(CreateEnvironment);
WorkflowPage
里面的所有组件Environment
都是使用 Formik 模式的表单。一个示例组件是:
interface Props {
certificate?: CertificateStep;
onUpdate?: (key: string, value: any) => void;
}
class Certificate extends Component<Props> {
private submitForm: (
e?: React.FormEvent<HTMLFormElement> | undefined
) => void;
public render() {
const { formValues } = this.props.certificate!;
console.log(formValues); //tslint:disable-line
return (
<Form
className="license"
type="horizontal"
initialValues={formValues}
onSubmit={this.onSubmit}
>
{formProps => {
this.submitForm = formProps.handleSubmit;
return (
<Fragment>
<CheckboxField
name="productSpecific"
id="productSpecific"
type="toggle"
>
Provide Product Specific Certificate
</CheckboxField>
<SelectField name="certificate" label="Certificate">
<SelectOption value="">---Select Certificate---</SelectOption>
</SelectField>
</Fragment>
);
}}
</Form>
);
}
public handleSubmit = () => {
this.submitForm();
}
private onSubmit = (values: FormValues, actions: FormActions) => {
this.props.onUpdate!('certificate', values);
actions.setSubmitting(false);
}
}
export default Certificate;
单击下一个WorkflowButton
时,通过传递操作 updateEnvironmentWorkflow 来更新 redux 状态。动作是这样的:
export interface UpdateEnvironmentWorkflow {
type: Constants.UPDATE_ENVIRONMENT_WORKFLOW;
payload: {
key: string;
value: any;
};
}
export type CreateEnvironmentAction = UpdateEnvironmentWorkflow;
export const updateEnvironmentWorkflow = (
key: string,
value: any
): UpdateEnvironmentWorkflow => ({
payload: { key, value },
type: Constants.UPDATE_ENVIRONMENT_WORKFLOW
});
我的减速机是这样的:
const createEnvironment = (
state: CreateEnvironment = initialState.createEnvironment,
action: CreateEnvironmentAction
) => {
switch (action.type) {
case Constants.UPDATE_ENVIRONMENT_WORKFLOW:
return {
...state,
[action.payload.key]: {
...state[action.payload.key],
formValues: action.payload.value
}
};
default:
return state;
}
};
export default createEnvironment;
现在奇怪的是,如果我单击下一个按钮,redux 状态会更新为新值。如果我导航到其他页面并返回创建环境,我的表单值将显示来自 redux 存储状态的更新值。
但是,如果我只是点击上一个按钮,我的状态值不会显示更新的值。证书的 render() 中的 console.log(formValues) 仅显示初始值。
任何帮助将不胜感激。谢谢。
Form的initialValues也是Formik的initialValues。这也可能是一个formik问题