All Articles

Creating a Reddit Clone Using React and GraphQL - 05

inner peace

This is a series of posts and the previous one you can find from here.

Learning React with Ben Awad — 04

In the previous post, we set the cookie in the browser. We send the response with Set-Cookie header and browser(client) set the cookie. When we are sending any request to the server, the browser will attach the cookie to request. So, now we are going to prove it. Let’s create a me query in UserResolver.

After adding it we can test in GraphQL playground. Here is the me query.

query{
  me{
    id
  }
}

If you are logged in you can check that in developed tool’s Application section you will see qid and this query will return userId.

Now we successfully set the cookie. Let’s see what is the anatomy in here.

Once we execute below code line, whatever the data that we set on session will set on the Redis.

req.session.userId = user.id;

So, Redis will store data something like this {userId: 3} . Redis store this as key-value pairs.

sess: asdasdaioodasdjmdsjkf -> {userId: 3}

Then this key’s encrypt and send back to the client from Set-Cookie header. This will do by express-session middleware. Whenever we make a request this cookie attached to the request and send to the server. Then express-session will decrypt this by using the secret that we specify in the session config object. The using that key, session will retrieve the data from Redis. I hope this explanation helps to understand the whole picture.

At this point, we have come a long way with adding the back-end to this app. So, now we are moving to build a front-end application for the Reddit Clone app.

We are using Next.js to create the front-end app. Specifically with chakra-ui. Please use the below command to create the front-end application.

yarn create next-app --example with-chakra-ui reddit-web-app

You can give any name for reddit-web-app because this is the folder that I going to put this codebase.

VS Code Tips: You can open this project in the same VS Code by adding folder to workspace option in File tab.

We don’t want this template code. So we remove it and change the extension of index.js and _app.js files .tsx

Then we need to install @type packages by using the below command.

yarn add --dev typescript @types/node

But we can keep the _app.tsxfile content. Now we can hit the yarn dev check that you can run the application.

Now we are creating the Register page. To do that I will add the file to page folder. Then we are adding the register form.

To do that first add formik

yarn add formik

Generally, we can add below and make a specific User Register page.

export const Register: React.FC<registerProps> = ({}) => {
  return (
    <Wrapper variant="small">
      <Formik
        onSubmit={(value) => {
          console.log(value);
        }}
        initialValues={{ username: "", password: "" }}
      >
        {(values) => (
          <Form>
            <FormControl>
              <FormLabel htmlFor="username">Username:</FormLabel>
              <Input
                value={values.username}
                id="username"
                placeholder="username"
              />
            </FormControl>
          </Form>
        )}
      </Formik>
    </Wrapper>
  );
};

But, we can use this input field as a generic input filed and reuse it. Let’s do that next. We are creating InputField component. Inside it, we are using useFiled hook. This is coming from fomik . We define the type for InputFieldProps as InputHTMLAttributes<HTMLInputElement> but once you pass the props to useField it will tell that name is missing. The reason is in InputHTMLAttributes name is optional and useField ‘s name is required field. To make it required, we can add an object as below code.

type InputFieldProps = InputHTMLAttributes<HTMLInputElement> & { name: string };

After adding props, we will have InputField like this…

export const InputField: React.FC<InputFieldProps> = ({
  label,
  size: _,
  ...props
}) => {
  const [field, { error }] = useField(props);
  return (
    <FormControl isInvalid={!!error}>
      <FormLabel htmlFor={field.name}>{label}</FormLabel>
      <Input
        {...props}
        {...field}
        id={field.name}
        placeholder={props.placeholder}
      />
      {error ? <FormErrorMessage>{error}</FormErrorMessage> : null}
    </FormControl>
  );
};

Then we can replace the username filed with InputField in register.tsx page. With this, we can any number of fields with passing the props to it.

With this, we can complete the register page. In the next post, we are going to make graphql requests to our web server.

The codebase for this article that can find in here.

rasikag/reddit-clone-webapp

I will wrap-up this note from here. Soon I will publish the next part of this note.

If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.

That’s for today friends. See you soon. Thank you.

References:

This article series based on the Ben Award - Fullstack React GraphQL TypeScript Tutorial.

Main image credit