-
Notifications
You must be signed in to change notification settings - Fork 3
06 Forms
JP Barbosa edited this page Apr 18, 2021
·
2 revisions
code ./src/hooks/useForm.ts
import { useState } from 'react';
export type IChangeElement =
| HTMLInputElement
| HTMLSelectElement
| HTMLTextAreaElement;
export const useForm = <T>(initialState: T) => {
const [formState, setFormState] = useState<T>(initialState);
const handleChange = (event: React.ChangeEvent<IChangeElement>): void => {
const { tagName, name, value } = event.target;
const parsedValue = tagName === 'SELECT' && value === '' ? null : value;
setFormState({ ...formState, [name]: parsedValue });
};
return { formState, setFormState, handleChange };
};
code ./src/pages/Article/index.tsx
...
import { ArticleFormFields } from './FormFields';
export const ArticleIndex: React.FC = () => {
...
const emptyRecord = {
title: '',
text: '',
};
return (
<RecordIndex<Article>
...
FormFields={ArticleFormFields}
emptyRecord={emptyRecord}
/>
);
}
code ./src/interfaces/PagesProps.ts
export interface RecordIndexProps<T> {
...
FormFields: React.FC<FormFieldsProps<T>>;
emptyRecord: T;
}
...
code ./src/pages/Record/index.tsx
...
import { RecordMutations } from './Mutations';
export const RecordIndex = <T extends Record>({
...
FormFields,
emptyRecord,
}: RecordIndexProps<T>) => {
...
return (
<div className="page">
<div className="content">
...
<RecordMutations<T>
FormFields={FormFields}
activeRecord={emptyRecord}
/>
</div>
</div>
);
};
code ./src/interfaces/PagesProps.ts
...
export interface RecordMutationsProps<T> {
FormFields: React.FC<FormFieldsProps<T>>;
activeRecord: T;
}
code ./src/pages/Record/Mutations.tsx
import { Record } from '../../interfaces/RecordEntities';
import { RecordMutationsProps } from '../../interfaces/PagesProps';
import { RecordNew } from './New';
export const RecordMutations = <T extends Record>({
FormFields,
activeRecord,
}: RecordMutationsProps<T>) => {
return (
<div className="mutations">
<RecordNew<T> FormFields={FormFields} activeRecord={activeRecord} />
</div>
);
};
code ./src/interfaces/PagesProps.ts
...
export interface RecordNewProps<T> {
FormFields: React.FC<FormFieldsProps<T>>;
activeRecord: T;
}
code ./src/pages/Record/New.tsx
import { Record } from '../../interfaces/RecordEntities';
import { RecordNewProps } from '../../interfaces/PagesProps';
import { RecordForm } from './Form';
export const RecordNew = <T extends Record>({
FormFields,
activeRecord,
}: RecordNewProps<T>) => {
return (
<div className="new">
<h2>New</h2>
<RecordForm FormFields={FormFields} activeRecord={activeRecord} />
</div>
);
};
code ./src/interfaces/PagesProps.ts
...
export interface RecordFormProps<T> {
FormFields: React.FC<FormFieldsProps<T>>;
activeRecord: T;
}
code ./src/pages/Record/Form.tsx
import { Record } from '../../interfaces/RecordEntities';
import { RecordFormProps } from '../../interfaces/PagesProps';
import { useForm } from '../../hooks/useForm';
export const RecordForm = <T extends Record>({
FormFields,
activeRecord,
}: RecordFormProps<T>) => {
const { formState, handleChange } = useForm<T>(activeRecord);
return (
<div>
<form>
<FormFields formState={formState} handleChange={handleChange} />
<input type="submit" />
</form>
</div>
);
};
code ./src/interfaces/PagesProps.ts
import { IChangeElement } from '../hooks/useForm';
...
export interface FormFieldsProps<T> {
formState: T;
handleChange: (event: React.ChangeEvent<IChangeElement>) => void;
}
code ./src/pages/Article/FormFields.tsx
import { useFetch } from '../../hooks/useFetch';
import { FormFieldsProps } from '../../interfaces/PagesProps';
import { Article, Author } from '../../interfaces/RecordEntities';
type IProps = FormFieldsProps<Article>;
export const ArticleFormFields: React.FC<IProps> = ({
formState,
handleChange,
}) => {
const authorsFetch = useFetch<Author>('authors');
return (
<div>
<div>
<label>Title</label>
<input
type="text"
name="title"
value={formState.title}
onChange={handleChange}
/>
</div>
<div>
<label>Text</label>
<textarea
name="text"
value={formState.text}
onChange={handleChange}
rows={5}
/>
</div>
<div>
<label>Author</label>
<select
name="author"
value={formState.author ? formState.author.id : ''}
onChange={handleChange}
>
<option value="">Select</option>
{authorsFetch.records.map((author) => (
<option key={author.id} value={author.id}>
{author.name}
</option>
))}
</select>
</div>
</div>
);
};
git add .
git commit -m "Forms"