ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #2-4 커스텀 훅 재사용 및 홈 화면 설정,useCallback
    React로 nodebirdSNS 만들기 (인프런)/#2 SNS 화면 만들기 2020. 1. 7. 12:39

    쪼개기

    - 리액트는 한 페이지에서 모든걸 다 만들면 여러 컴포넌트가 리랜더링 되기때문에 별도의 컴포넌트로 나눠주는게좋다.

     (*쪼개면 부모컴포넌트, 자식컴포넌트로 나눠지기때문에 관리에 약간의 어려움이 있는건 사실.*)

     

     

     

    - components폴더-> LoginForm.js

    import React, { useState, useCallback } from "react";
    import Link from "next/link";
    import { Form, Input, Button } from "antd";
    import { useInput } from "../pages/signup";
    
    // useCallback으로 감싸는 함수기준은 자식 컴포넌트에 넘겨주는 함수는 무조건 감싸준다고 보면됨
    const LoginForm = () => {
      const [id, onChangeId] = useInput("");
      const [password, onChangePassword] = useInput("");
      const onSubmitForm = useCallback(
        e => {
          e.preventDefault();
          console.log({
            id,
            password
          });
        },
        [id, password]
      );
    
      return (
        <Form onSubmit={onSubmitForm}>
          <div>
            <label htmlFor="user-id">아이디</label>
            <br />
            <Input name="user-id" value={id} onChange={onChangeId} required />
          </div>
          <div>
            <label htmlFor="user-password">비밀번호</label>
            <br />
            <Input
              name="user-password"
              type="password"
              value={password}
              required
              onChange={onChangePassword}
            />
          </div>
          <div>
            <Button type="primary" htmlType={"submit"} loading={false}>
              로그인
            </Button>
            <Link href="/signup">
              <a>
                <Button>회원가입</Button>
              </a>
            </Link>
          </div>
        </Form>
      );
    };
    
    export default LoginForm;
    

    - AppLayout.js

    import React, { children } from "react";
    import Link from "next/link";
    import PropTypes from "prop-types";
    import { Menu, Input, Row, Col, Card, Avatar, Form } from "antd";
    import LoginForm from "./LoginForm";
    
    // 가짜 데이터
    const dummy = {
      nickname: "정중식",
      Post: [],
      Following: [],
      Follower: [],
      isLoggedIn: false
    };
    
    const AppLayout = ({ children }) => {
      return (
        <div>
          <Menu mode="horizontal">
            <Menu.Item key="home">
              <Link href="/">
                <a>노드버드</a>
              </Link>
            </Menu.Item>
            <Menu.Item key="profile">
              <Link href="/profile">
                <a>프로필</a>
              </Link>
            </Menu.Item>
            <Menu.Item key="mail">
              <Input.Search enterButton style={{ verticalAlign: "middle" }} />
            </Menu.Item>
          </Menu>
    
          <Row>
            <Col xs={24} md={6}>
              {dummy.isLoggedIn ? (
                <Card
                  actions={[
                    <div key="twit">
                      짹짹
                      <br />
                      {dummy.Post.length}
                    </div>,
                    <div key="following">
                      팔로잉
                      <br />
                      {dummy.Following.length}
                    </div>,
                    <div key="follower">
                      팔로워
                      <br />
                      {dummy.Follower.length}
                    </div>
                  ]}
                >
                  <Card.Meta
                    avatar={<Avatar>{dummy.nickname[0]}</Avatar>}
                    title={dummy.nickname}
                  />
                </Card>
              ) : (
                <LoginForm />
              )}
            </Col>
            <Col xs={24} md={12}>
              {children}
            </Col>
            <Col xs={24} md={6}></Col>
          </Row>
        </div>
      );
    };
    
    AppLayout.propTypes = {
      children: PropTypes.node
    };
    
    export default AppLayout;
    

    커스텀 훅 재사용

    - signup.js파일에서 사용한 커스텀 훅을 LoginForm.js 파일에서도 사용해준다

     

    - 커스텀 훅은 리액트에서 form 처리 이벤트 중복을 최소화시켜줘서 좋다.

    // 커스텀 훅
    export const useInput = (initValue = null) => {
      const [value, setter] = useState(initValue);
      const handler = useCallback(e => {
        setter(e.target.value);
      }, []);
      return [value, handler];
    };

    useCallBack()

    - useCallback으로 감싸는 함수기준은 자식 컴포넌트에 넘겨주는 함수는 무조건 감싸준다고 보면됨

     

    - jsx에 들어가는 함수인 경우에 useCallback으로 감싸주셔야 합니다. <button onClick={onClick}>처럼 jsx에 들어가는 onClick에요.

     

    - 감싸주지 않으면 onClick 함수가 리렌더링 시마다 새로 만들어집니다. 함수를 새로 만드는 것은 낭비입니다. 새로 만들어지는 것을 막기 위해서 []를 사용하는 거고, 새로 만들어주어야 하는 특별한 경우가 생기는데(useCallback에서 사용하는 state가 바뀐다거나) 그럴 때 새로 만드는 기준이 될 state를 배열 안에 넣어줍니다.

       .[] 빈 대괄호는 한번만 리렌더링 된다는뜻이고, 대괄호안에 새로만드는 기준이될 state를 배열안에넣어주면 []안의 내용이 바뀔때마다 리렌더링 , 즉 함수가 새롭게 생성됨

    댓글

Designed by Tistory.