2

我有一个奇怪的场景,在我的 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问题

4

0 回答 0