У меня странный сценарий, в котором внутри моих инструментов разработки 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.info("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.info(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 состояние redux обновляется путем передачи действия updateEnvironmentWorkflow. Действие похоже:
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.
НО, если я просто нажму предыдущую кнопку, мои значения состояния не будут отображать обновленные значения. В console.info (formValues) внутри render () сертификата отображаются только начальные значения.
Любая помощь будет оценена по достоинству. Спасибо.
Также initialValues of Form - это Formik initialValues. Возможно, это тоже проблема с формиком





У меня аналогичная проблема. Вы нашли решение, почему вы не получаете обновленное состояние?