NodeBird 1-1

학습자료 제로초님 인프런강의 - NodeBird SNS만들기

1. ant design과 styled-components

ant design

요런 사이트
버튼 아이콘 뱃지 댓글 팝업 등등 같은거 미리 다 만들어놓고 있기 때문에 가져다 쓰면 됨

styled-components

component 자체에 css를 입혀서 컴포넌트로 만듦.
emotion을 더 많이 쓰긴하는데 styled component 익혀놓으면 emotion 공식문서만 쫙 봐도 쓸 수 있음!
emotion은 서버 사이드 렌더링할때 좀 더 편하다.

antd와 style-component 설치하기

터미널에 다음과 같이 입력.

npm i antd styled-components @ant-design/icons
  • icon같이 용량이 큰 파일은 따로 설치해야하는 경우가 많음.

공통 레이아웃 - 메뉴창 가져와보기

AppLayout.js에 import로 antd 불러오기.
import { 가져올 컴포넌트 } from 'antd';

import { Menu } from 'antd';

const AppLayout = ({ children }) => {
  return (
    <div>
      <Menu mode="horizontal">
        <Menu.Item>
          <Link href="/"><a>노드버드</a></Link>
        </Menu.Item>
        <Menu.Item>
          <Link href="/profile"><a>프로필</a></Link>
        </Menu.Item>
        <Menu.Item>
          <Link href="/signup"><a>회원가입</a></Link>
        </Menu.Item>
      </Menu>
      {children}
    </div>
  )
};

그리고 antd import하기 (next 안에 웹팩이 들어있어서 css파일 import 가능)
그런데 메뉴창은 모든 페이지에서 다 사용되기 때문에 AppLayout에 import하면 안됨.
모든 페이지들에 공통으로 들어갈 내용을 담을 파일을 생성한다. ( pages/_app.js)

import Head from 'next/head';
import 'antd/dist/antd.css';

const NodeBird = ({ Component }) => {
  return(
      <Component />
  )
};

export default NodeBird;
  • 모든 페이지에 공통으로 들어갈 내용 = App.js
  • 일부 페이지들에서만 공통 =

적용된 모습!

가져온 antd에 style을 줘서 디자인을 수정할 수 있다.

  • 그런데 사실 이건 잘못된 사용법이었음! 다음에 다룰 예정.


    2.Head

body 말고 head 내의 내용을 수정하고 싶을 때 (타이틀같은거)
Next에서 제공하는 Head 컴포넌트를 사용

  import Head from 'next/head';

...

  return(
   <>
      <Head>
        <meta charSet="utf-8" />
        <title>NodeBird</title>
      </Head>
      ...
   </>
  )

이것도 마찬가지로 모든 페이지에 공통인 내용은 App.js에, 특정 페이지에서만 바꿔줄 내용은 Layout에.


3. 반응형 그리드

antd의 Row, Col 이용.

<Row>
  <Col xs={24} md={6} />
  <Col xs={24} md={12} />
  <Col xs={24} md={6} />
</Row>

xs = 모바일 / sm = 태블릿 / md = 작은 데스크탑

antd는 총 24개의 그리드(세로줄)을 기준으로 함.

<Col xs={12} md={6} />
<Col xs={12} md={12} />

만약 이렇게 쓴다면 xs={12} + xs={12}가 24를 넘지 않아서 한 줄에 두개가 나열될 수 있음.
xs={12} + xs={13}이면 24가 넘으니 세로정렬됨.

※ 그리고 이건 다른 얘기지만 링크 걸면서 나온 얘기인데 a 태그의 target="_blank"는 보안 위험이 있음.
rel="noreferrer noopener"도 같이 써줘야 보안위험이 해결됨.


4. 로그인폼 만들기

아직 서버가 없으니 로그인 여부를 판단하기 위해 더미데이터를 이용할 것.
상태를 저장할 수 있는 state 사용.

// AppLayout 안에
const [isLoggedIn, setIsLoggedIn] = useState(false);

// 왼쪽메뉴 자리에
{isLoggedIn? <userProfile /> : <LoginForm />}

이렇게 임시로 만들어놓고 나중에 해당하는 내용들을 만든다.

참고로 컴포넌트 들은 이렇게 따로 폴더를 만들어 관리한다.

LoginForm

import React, { useState, useCallback } from 'react';
import { Form, Input, Button } from 'antd';
import Link from 'next/link';

const LoginForm = () => {
  const [id, setId] = useState('');
  const [password, setPassword] = useState('');

  const onChangeId = useCallback((e) => { //component에 props로 넘겨주는 함수는 useCallback을 꼭 써야 최적화가 됨!
    setId(e.target.value);
  }, []);

const onChangePassword = useCallback((e) => { 
    setPassword(e.target.value);
  }, []);

  return (
    <Form>
      <div>
        <label htmlForr="user-id">아이디</label>
        <br />
        <Input name="user-id" value={id} onChange={onChangeId} required />
      </div>
      <div>
        <label htmlForr="user-password">비밀번호</label>
        <br />
        <Input name="user-password" type="password" value={password} onChange={onChangePassword} required />
      </div>
      <div>
        <Button type="primary" htmlType="submit" loading={false}>로그인</Button>
        <Link href="/signup"><a><Button>회원가입</Button></a></Link>
      </div>
    </Form>
  )
}

export default LoginForm;

좋은 웹페이지 즐겨찾기