Frontend Serverless with React and GraphQL

Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.


28. Add a Create Recipe Form

Objective: Add the start of our create recipe form component.

Now that we have a create recipe route, let's create the component that will contain the form for editing a recipe. For now, the form will only have a submit button and we will manage the state of the form through a submitForm hook.

components/CreateRecipe.tsx

import { Row, Col, Form, Button } from 'antd';
import { submitForm } from '../utils/submitForm';
export const CreateRecipe = () => {
const initiateCreateRecipe = () => {
console.log('submitted form');
};
const { inputs, handleSubmit } = submitForm({}, initiateCreateRecipe);
return (
<Form onFinish={handleSubmit}>
<Row>
<Col span={16} />
<Col span={4}>
<Form.Item label="Create Recipe">
<Button type="primary" htmlType="submit">
Create Recipe
</Button>
</Form.Item>
</Col>
</Row>
</Form>
);
};

The submit form hook works by storing the state within a useState hook in react. We can call setInputs to set the current state of the hook and inputs for reading the state. We can pass in an intialValues object which will have all of the default values that the form will use, as well as a callback function which will enable us to have the submitForm hook execute functionality that we define in the <CreateRecipe>. After executing the callback, we reset the form back to its default state.

utils/submitForm.ts

import { useState } from 'react';
export const submitForm = (initialValues, callback) => {
const [inputs, setInputs] = useState(initialValues);
const handleSubmit = () => {
callback();
setInputs(() => ({ ...initialValues }));
};
return {
inputs,
handleSubmit,
};
};

Now that the <CreateRecipe> component has been created, let's use it on the create page:

pages/create.tsx

import { MainLayout } from '../components/layout/MainLayout';
import styled from 'styled-components';
import { CreateRecipe } from '../components/CreateRecipe';
const StyledHeader = styled.h1`
${({ theme }) => `
padding: ${theme['padding-small']} ${theme['padding-small']};
`}
`;
const Create = () => {
return (
<MainLayout title="Create Recipe">
<StyledHeader>Create Recipe</StyledHeader>
<CreateRecipe />
</MainLayout>
);
};
export default Create;