Refactor ReviewForm: use Form connector from Final Form

This commit is contained in:
Vesa Luusua 2018-04-16 23:15:08 +03:00
parent 3c4513a0d2
commit 0080cbd298
4 changed files with 122 additions and 109 deletions

View file

@ -1,41 +1,52 @@
/* eslint-disable no-console */
import React from 'react';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import { Form as FinalForm, FormSpy } from 'react-final-form';
import * as validators from '../../util/validators';
import { Button } from '../../components';
import FieldReviewRating from './FieldReviewRating';
const formName = 'Styleguide.FieldReviewRating.Form';
const FormComponent = props => {
const { form, handleSubmit, invalid, pristine, submitting } = props;
const required = validators.required('This field is required');
const submitDisabled = invalid || pristine || submitting;
const FormComponent = props => (
<FinalForm
{...props}
form={formName}
render={fieldRenderProps => {
const { form, handleSubmit, onChange, invalid, pristine, submitting } = fieldRenderProps;
const required = validators.required('This field is required');
const submitDisabled = invalid || pristine || submitting;
return (
<form onSubmit={handleSubmit}>
<FieldReviewRating
id={`${form}.rate1`}
name="rating"
label="Rate your experience"
validate={required}
/>
<Button style={{ marginTop: 24 }} type="submit" disabled={submitDisabled}>
Submit
</Button>
</form>
);
};
FormComponent.propTypes = formPropTypes;
const Form = reduxForm({
form: formName,
})(FormComponent);
return (
<form
onSubmit={e => {
e.preventDefault();
handleSubmit(e);
}}
>
<FormSpy onChange={onChange} />
<FieldReviewRating
id={`${form}.rate1`}
name="rating"
label="Rate your experience"
validate={required}
/>
<Button style={{ marginTop: 24 }} type="submit" disabled={submitDisabled}>
Submit
</Button>
</form>
);
}}
/>
);
export const StarRating = {
component: Form,
component: FormComponent,
props: {
onChange: formState => {
if (formState.dirty) {
console.log('form values changed to:', formState.values);
}
},
onSubmit: values => {
console.log('submit values:', values);
},

View file

@ -1,11 +1,7 @@
/**
* DEPRECATED: this component is part of Redux Form - we are migrating to react-final-form.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { intlShape, injectIntl } from 'react-intl';
import { Field } from 'redux-form';
import { Field } from 'react-final-form';
import classNames from 'classnames';
import { IconReviewStar, ValidationError } from '../../components';

View file

@ -4,6 +4,7 @@ import ReviewForm from './ReviewForm';
export const Empty = {
component: ReviewForm,
props: {
formId: 'ReviewFormExample',
onSubmit: values => {
console.log('Submit ReviewForm with (unformatted) values:', values);
},

View file

@ -1,103 +1,107 @@
import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import { intlShape, injectIntl, FormattedMessage } from 'react-intl';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { Form as FinalForm } from 'react-final-form';
import classNames from 'classnames';
import { isTransactionsTransitionAlreadyReviewed } from '../../util/errors';
import { propTypes } from '../../util/types';
import { required } from '../../util/validators';
import { FieldReviewRating, Form, PrimaryButton, TextInputField } from '../../components';
import { FieldReviewRating, Form, PrimaryButton, FieldTextInput } from '../../components';
import css from './ReviewForm.css';
const ReviewFormComponent = props => {
const {
className,
rootClassName,
disabled,
handleSubmit,
intl,
form,
invalid,
submitting,
reviewSent,
sendReviewError,
sendReviewInProgress,
} = props;
const ReviewFormComponent = props => (
<FinalForm
{...props}
render={fieldRenderProps => {
const {
className,
rootClassName,
disabled,
handleSubmit,
intl,
formId,
invalid,
submitting,
reviewSent,
sendReviewError,
sendReviewInProgress,
} = fieldRenderProps;
const reviewRating = intl.formatMessage({ id: 'ReviewForm.reviewRatingLabel' });
const reviewRatingRequiredMessage = intl.formatMessage({
id: 'ReviewForm.reviewRatingRequired',
});
const reviewRating = intl.formatMessage({ id: 'ReviewForm.reviewRatingLabel' });
const reviewRatingRequiredMessage = intl.formatMessage({
id: 'ReviewForm.reviewRatingRequired',
});
const reviewContent = intl.formatMessage({ id: 'ReviewForm.reviewContentLabel' });
const reviewContentPlaceholderMessage = intl.formatMessage({
id: 'ReviewForm.reviewContentPlaceholder',
});
const reviewContentRequiredMessage = intl.formatMessage({
id: 'ReviewForm.reviewContentRequired',
});
const reviewContent = intl.formatMessage({ id: 'ReviewForm.reviewContentLabel' });
const reviewContentPlaceholderMessage = intl.formatMessage({
id: 'ReviewForm.reviewContentPlaceholder',
});
const reviewContentRequiredMessage = intl.formatMessage({
id: 'ReviewForm.reviewContentRequired',
});
const errorMessage = isTransactionsTransitionAlreadyReviewed(sendReviewError) ? (
<p className={css.error}>
<FormattedMessage id="ReviewForm.reviewSubmitAlreadySent" />
</p>
) : (
<p className={css.error}>
<FormattedMessage id="ReviewForm.reviewSubmitFailed" />
</p>
);
const errorArea = sendReviewError ? errorMessage : <p className={css.errorPlaceholder} />;
const errorMessage = isTransactionsTransitionAlreadyReviewed(sendReviewError) ? (
<p className={css.error}>
<FormattedMessage id="ReviewForm.reviewSubmitAlreadySent" />
</p>
) : (
<p className={css.error}>
<FormattedMessage id="ReviewForm.reviewSubmitFailed" />
</p>
);
const errorArea = sendReviewError ? errorMessage : <p className={css.errorPlaceholder} />;
const reviewSubmitMessage = intl.formatMessage({
id: 'ReviewForm.reviewSubmit',
});
const reviewSubmitMessage = intl.formatMessage({
id: 'ReviewForm.reviewSubmit',
});
const classes = classNames(rootClassName || css.root, className);
const submitInProgress = submitting || sendReviewInProgress;
const submitDisabled = invalid || disabled || submitInProgress;
const classes = classNames(rootClassName || css.root, className);
const submitInProgress = submitting || sendReviewInProgress;
const submitDisabled = invalid || disabled || submitInProgress;
return (
<Form className={classes} onSubmit={handleSubmit}>
<FieldReviewRating
className={css.reviewRating}
id={`${form}.starRating`}
name="reviewRating"
label={reviewRating}
validate={required(reviewRatingRequiredMessage)}
/>
return (
<Form className={classes} onSubmit={handleSubmit}>
<FieldReviewRating
className={css.reviewRating}
id={formId ? `${formId}.starRating` : 'starRating'}
name="reviewRating"
label={reviewRating}
validate={required(reviewRatingRequiredMessage)}
/>
<TextInputField
className={css.reviewContent}
type="textarea"
name="reviewContent"
id={`${form}.reviewContent`}
label={reviewContent}
placeholder={reviewContentPlaceholderMessage}
validate={[required(reviewContentRequiredMessage)]}
/>
<FieldTextInput
className={css.reviewContent}
type="textarea"
id={formId ? `${formId}.reviewContent` : 'reviewContent'}
name="reviewContent"
label={reviewContent}
placeholder={reviewContentPlaceholderMessage}
validate={required(reviewContentRequiredMessage)}
/>
{errorArea}
<PrimaryButton
className={css.submitButton}
type="submit"
inProgress={submitInProgress}
disabled={submitDisabled}
ready={reviewSent}
>
{reviewSubmitMessage}
</PrimaryButton>
</Form>
);
};
{errorArea}
<PrimaryButton
className={css.submitButton}
type="submit"
inProgress={submitInProgress}
disabled={submitDisabled}
ready={reviewSent}
>
{reviewSubmitMessage}
</PrimaryButton>
</Form>
);
}}
/>
);
ReviewFormComponent.defaultProps = { className: null, rootClassName: null, sendReviewError: null };
const { bool, func, string } = PropTypes;
ReviewFormComponent.propTypes = {
...formPropTypes,
className: string,
rootClassName: string,
intl: intlShape.isRequired,
@ -107,6 +111,7 @@ ReviewFormComponent.propTypes = {
sendReviewInProgress: bool.isRequired,
};
const formName = 'ReviewForm';
const ReviewForm = compose(injectIntl)(ReviewFormComponent);
ReviewForm.displayName = 'ReviewForm';
export default compose(reduxForm({ form: formName }), injectIntl)(ReviewFormComponent);
export default ReviewForm;