일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 주짓떼로
- 솔로드릴
- 자바스크립트
- 주짓수
- 파이썬
- 영화리뷰
- 영화
- web
- JavaScript
- graphQL
- Redux
- 클로즈가드
- 프로그래밍
- 드릴
- 개발자
- 노드
- git
- 하프가드
- REACT
- 개발
- 영화감상
- Express
- 주짓떼라
- nodejs
- 리액트
- 엄티로드
- 웹개발
- Node
- 디자인패턴
- development
- Today
- Total
As i wish
[React SNS] React SNS 만들기 - 1 본문
안녕하세요. 엄티입니다.
오늘은 React 를 사용하여 간단한 SNS 를 만들어 볼껀데요.
제 포스팅은 '제로초' 님의 강의를 바탕으로 복습용으로 작성됩니다.
자세한 설명을 원하면 밑에 강의를 참조해 주세요.
무튼 기본적으로 Front/Back 을 구성하고요.
Front 는 React, Redux, Next 등을 사용할 예정 입니다.
먼저 기본적으로 front/back DIR을 만들어 줍니다. 그리고 front부터 구성 할 것인데요.
front/package.json
{
"name": "react-nodebird-front",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "next",
"build": "next build",
"start": "next start"
},
"author": "TeiEom",
"license": "ISC",
"dependencies": {
"antd": "^3.20.5",
"next": "^9.0.2",
"react": "^16.8.6",
"react-dom": "^16.8.6"
},
"devDependencies": {
"eslint": "^6.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^1.6.1",
"nodemon": "^1.19.1",
"webpack": "^4.36.1"
}
}
프론트의 package.json은 다음과 같이 구성 합니다. 기본적인 react, react-dom 을 깔아주시고 사용하기로한 next를 깔아줍니다.
$ npm install // 설치
$ npm run dev // 실행
순으로 하면 아마 localhost:3000 에서 확인해 보실 수 있습니다. (상황에 따라 포트가 바뀔 수도 있습니다.)
next 는 SSR 을 할 수 있게 해주는 모듈인데 저도 이번에 처음 사용해 봤습니다.
그 외의 next의 장점이 몇가지 있는데요. 다음과 같습니다.
1. 기존 웹팩에서 사용했던 hot-loader 같은것들도 한번에 적용됩니다.
2. react-router 를 사용하지 않아도 기본적인 router 시스템이 적용되어서 아주 편했습니다.
3. 주소체계를 만들어 주어서 파일 구조 안에 "pages" 란 폴더 를 만들고 그 안에 파일을 만들어 주면 자동으로 주소 체계가 잡히더라고요. 예를 들어 pages/about.js 또는 pages/user/create.js 를 각각 만들어 주면 실제 주소에서도 /about -> pages/about.js 가 실행 되고, /user/create -> pages/user/create.js 가 실행되는것을 보실 수 있습니다.
4. React code 상단에 import React from 'react'를 하지 않아도 알아서 처리해주는 아주 똑똑한 친구더군요.
5. 그 외에도 SSR 뿐만 아니라 code spolit 까지 도와주어서 SSR 를 적용하기에 아주 좋은 모듈이죠.
위의 폴더 구조 처럼 pages 안에서 각각 필요한 화면을 만들어주고 자연스럽게 주소 체계로 사용하면 됩니다.
여기 까지 간단한 Next JS 에 대하여 알아봤고요 코드로 들어가보겠습니다.
일단 완성된 화면은 다음과 같은데요.
헤더에 NodeBird, Profile, 검색창 이 있고 SignUp 버튼이 있습니다.
그 밑에 이제 content (Hello, Next!) 가 보이겠죠?
일단 페이지는 총 3페이지이니 각각 index.js, profile.js, signup.js 로 구성했습니다.
pages/index.js
import React from 'react'; // eslint 에서 react 쓰면 import 하라고 명시됨
import Link from 'next/link';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
const Home = () => {
return (
<>
<Head>
<title>NodeBird</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.20.5/antd.css"/>
</Head>
<AppLayout>
<div>
Hello, Next!
</div>
</AppLayout>
</>
);
};
export default Home;
pages/profile.js
import React from 'react';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
const Profile = () => {
return (
<>
<Head>
<title>NodeBird</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.20.5/antd.css"/>
</Head>
<AppLayout>
<div>
Profile!
</div>
</AppLayout>
</>
);
};
export default Profile;
pages/signup.js
import React, { useState } from 'react';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
import { Form, Input, Checkbox, Button } from 'antd';
const Signup = () => {
// const [id, setId] = useState(''); // Using custom hook in bottom
// const [nick, setNick] = useState(''); // Using custom hook in bottom
const [pass, setPass] = useState('');
const [passChk, setPassChk] = useState('');
const [term, setTerm] = useState('');
const [passError, setPassError] = useState(false);
const [termError, setTermError] = useState(false);
const onSubmit = (e) => {
e.preventDefault();
if (pass !== passChk) {
return setPassError(true);
}
if (!term) {
return setTermError(true);
}
console.log({
id, nick, pass, passChk, term
})
};
// const onChangeId = (e) => { // Using custom hook in bottom
// setId(e.target.value);
// };
// const onChangedNick = (e) => {
// setNick(e.target.value);
// };
const onChangePass = (e) => {
setPass(e.target.value);
};
const onChangePassChk = (e) => {
setPassError(e.target.value !== pass);
setPassChk(e.target.value);
};
const onChangeTerm = (e) => {
setTermError(false);
setTerm(e.target.checked);
};
// Custom hook
const useInput = (initValue = null) => {
const [value, setter] = useState(initValue);
const handler = (e) => {
setter(e.target.value);
};
return [value, handler];
}
const [id, onChangeId] = useInput('');
const [nick, onChangedNick] = useInput('');
return (
<>
<Head>
<title>NodeBird</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.20.5/antd.css"/>
</Head>
<AppLayout>
<Form onSubmit={onSubmit} style={{ padding: 10 }}>
<div>
<label htmlFor="user-id">ID</label>
<br/>
<Input name="user-id" required value={id} onChange={onChangeId}/>
</div>
<div>
<label htmlFor="user-nick">Nickname</label>
<br/>
<Input name="user-nick" required value={nick} onChange={onChangedNick}/>
</div>
<div>
<label htmlFor="user-pass">Password</label>
<br/>
<Input name="user-pass" type="password" required value={pass} onChange={onChangePass}/>
</div>
<div>
<label htmlFor="user-pass-chk">Password Check</label>
<br/>
<Input name="user-pass-chk" type="password" required value={passChk} onChange={onChangePassChk}/>
{passError && <div style={{ color: 'red' }}>Please check password</div>}
</div>
<div>
<Checkbox name="user-term" value={term} onChange={onChangeTerm}>
Are you agree this term?
</Checkbox>
{termError && <div style={{ color: 'red' }}>You must agrre term</div>}
</div>
<div>
<Button type="primary" htmlType="submit">Register</Button>
</div>
</Form>
</AppLayout>
</>
);
};
export default Signup;
특히 pages/signup.js 에서는 custumHook을 사용하였는데 참고 부탁드립니다. 기본적인것이긴 한데 Input tag는 항상 onChange 와 value 가 한 짝을 이루어서 value state에 event listener를 통하여 상태가 변할 수 있도록 도와주는 것이 좋습니다.
커스텀 훅은 사용자가 훅을 만드는 것으로 코드를 조금 더 짧게 만들어주고 반복작업을 줄여주요.
커스텀 훅 예제
const [id, setId] = useState('');
const [nick, setNick] = useState('');
const onChangeId = (e) => {
setId(e.target.value);
}
const onChangedNick = (e) => {
setNick(e.target.value);
}
// 이렇게 사용해야할 훅을 커스텀 훅으로 사용하게 되면 아주 간단해 집니다.
// 먼저 커스텀 훅을 만듭니다.
const useInput = (initValue = null) => {
const [value, setter] = useState(initValue);
const handler = (e) => {
setter(e.target.value);
};
return [value, handler];
}
// 그 다음 사용합니다.
// 아주 간단해 졌죠??
const [id, onChangeId] = useInput('');
const [nick, onChangedNick] = useInput('')
또한 각각의 코드의 <Head></Head> 부분이 있는데 이는 실제 html <head></head> 부분에 속하는 것이고 추후에 정리 하도록 하겠습니다.
또한 각각의 내용들을 <AppLayout></AppLayout> 으로 감싸주었는데 이는 Component 를 만들어서 자식들을 받아서 components/AppLayout.js 에서 띄워주도록 하였습니다.
components/Applyaout.js
import React from 'react';
import Link from 'next/link';
import { Menu, Input, Button } from 'antd';
const AppLayout = ({ children }) => {
return (
<div>
<Menu mode="horizontal">
<Menu.Item key="home">
<Link href="/">
<a>NodeBird</a>
</Link>
</Menu.Item>
<Menu.Item key="profile">
<Link href="/profile">
<a>Profile</a>
</Link>
</Menu.Item>
<Menu.Item key="mail">
<Input.Search enterButton style={{ verticalAlign: 'middle' }}/>
</Menu.Item>
</Menu>
<Link href="/signup">
<Button>SignUp</Button>
</Link>
{children}
</div>
)
};
export default AppLayout;
위 처럼 components/AppLayout.js 에서 children을 받고 헤더를 구성 하다음 밑에 {children} 을 통하여 content 를 띄워주도록 합니다. 여기서 children은 각각 pages/index.js, profile.js, signup.js 에 <AppLayout></AppLayout> 사이에 있는것 들이 되겠죠?
components/AppLayout.js 에서 'next/link'에 Link 를 사용하여 각각의 페이지로 이동 할 수 있게 구성한것도 보실 수 있습니다.
자세한 설명은 각각 코드의 주석으로 처리되어있습니다.
마지막으로 antd 를 쓰는것을 볼 수 있는데 이는 bootstrap 과 거의 똑같다고 보시면 됩니다.
bootstrap은 개발자로 하여금 간단한 스타일링을 해주는 뭐 그런건데 antd 도 비슷하더군요.
디자이너가 있으면 달라지겠지만 없는 상황에서는 간편하게 디자인하는것도 나쁘지 않다고 생각합니다.
이상 회원가입 페이지 만 동작하는 1강 포스팅을 마치겠습니다.
궁금 하신 점은 댓글로 달아주시고 전체 폴더 구조를 보여주고 포스팅을 줄이겠습니다.
'React JS' 카테고리의 다른 글
[React SNS] React SNS 만들기 - 3 (0) | 2019.08.06 |
---|---|
[React SNS] React SNS 만들기 - 2 (0) | 2019.07.30 |
[React JS] BookMark - 1 (0) | 2019.07.18 |
[React 틱 택 토] Redux - React 프로젝트 사용 (2) | 2019.07.18 |
[React 틱 택 토] Redux - React 프로젝트 세팅 (0) | 2019.07.18 |