4. Next.js and Chakra-ui

2020-10-01

Next.js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed.

Chakra UI is a simple, modular and accessible component library that gives you all the building blocks you need to build your React applications.

next.js/examples/with-chakra-ui/

프론트엔드를 위한 새로운 폴더를 만들고 Next.js와 Chakra-ui를 설치한다.

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

설치 후 components 폴더 안에 있는 파일을 전부 삭제 후, pages 폴더 안의 파일들의 확장자를 .tsx로 바꿔준다.

components/Wrapper.tsx

import { Box } from "@chakra-ui/core";
import React from "react";

interface WrapperProps {
  variant?: "small" | "regular";
}
/*typescript function component*/
const Wrapper: React.FC<WrapperProps> = ({ children, variant = "regular" }) => {
  return (
    <Box
      mt={8}
      mx="auto"
      maxW={variant === "regular" ? "800px" : "400px"}
      w="100%"
    >
      {children}
    </Box>
  );
};

export default Wrapper;

formik을 설치한다.

useField는 Formik에 입력을 자동으로 연결하도록 도와주는 custom React hook이다.

FormControl의 isInvalid로 children에게 prop의 전달 여부를 결정한다.

components/InputField.tsx

import React, { InputHTMLAttributes } from "react";
import { useField } from "formik";
import {
  FormControl,
  FormLabel,
  Input,
  FormErrorMessage,
} from "@chakra-ui/core";

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

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

export default InputField;

pages/register.tsx

interface registerProps {}

const Register: React.FC<registerProps> = ({}) => {
  return (
    <Formik
      initialValues=
      /*make these values available to render methods component as values.*/
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      /** whether the form is currently submitting */
      {({ isSubmitting }) => (
        <Wrapper variant="small">
          <Form>
            <InputField
              name="username"
              placeholder="username"
              label="Username"
            />
            <Box mt={4}>
              <InputField
                name="password"
                placeholder="password"
                label="Password"
                type="password"
              />
            </Box>
            <Button
              mt={4}
              type="submit"
              isLoading={isSubmitting}
              variantColor="teal"
            >
              register
            </Button>
          </Form>
        </Wrapper>
      )}
    </Formik>
  );
};

export default Register;

캡처