React + Typescript ํ๊ฒฝ์์ ๊ฐ๋ฐ
๐ ํ์
์คํฌ๋ฆฝํธ๋ antd์ ๋ด์ฅ๋์ด ์์ผ๋ฏ๋ก (ํ์
์คํฌ๋ฆฝํธ๋ฅผ) ๋ฐ๋ก ์ค์นํ์ง ์๋๋ค โก๏ธ @types/antd
์ค์น
$ npm install antd $ yarn add antd
์ฌ์ฉ
// src/App.tsx import React, { FC } from 'react'; import { Button } from 'antd'; // Button ์ปดํฌ๋ํธ import import './App.css'; const App = () => ( <div className="App"> <Button type="primary">Button</Button> // ์ปดํฌ๋ํธ ํ์ฉ </div> ); export default App;
โ๏ธ src/App.css ์ ์๋ ์ถ๊ฐํ๊ธฐ
@import '~antd/dist/antd.css';
๋๋ styledComponent ๋ก ์์ ๊ฐ๋ฅํ๋ค
๐จ styledComponent ์ ์ฉ ์์
import * as React from 'react'; import { styled } from 'styledComponents'; // styledComponents ์ ์ฉ(Component ์์ฑ) const Component = styled.div` width: 100%; font-size: 0.8em; color: ${p => p.theme.normal_color}; [data-container] { height: 60px; justify-content: center; } `; // IProps ์ธํฐํ์ด์ค ์์ฑ(ํ์ ์ง์ - string) interface IProps { className?: string; } class Footer extends React.Component<IProps> { render() { return ( <Component> // styledComponent๋ก ์คํ์ผ๋ง ํ ํ๊ทธ <div data-container> Co-working space, Floor 3rd, Hanoi 8:00 - 11:00 Sunday, Oct 14th, 2018 </div> </Component> ); } }
antd
๋ก ๋ค์ํ UI Component๋ฅผ ํ์ฉํ ์ ์์ง๋ง, ๋ํ์ ์ผ๋ก ์ฌ์ฉ๋๋ table
์ ํ์ฉํ๋ ์์๋ฅผ ์ค๋ช
ํด๋ณด์.
๐ coloum๊ณผ data๋ฅผ jsonํํ๋ก ์ง์ ํ, antd ์ปดํฌ๋ํธ์ ์์ฑ์ผ๋ก ๋ฃ์ด์ฃผ๋ ๋ฐฉ์์ด๋ค.
import { Table } from 'antd'; // table ๋ถ๋ฌ์ค๊ธฐ // columns ์ง์ (์ด 3๊ฐ์ columns์ด ์๊ธด๋ค) const columns = [ { title: 'Name', // title: ์ ๋ชฉ๋ผ์ธ dataIndex: 'name', // dataIndex: ์ค์ ๊ฐ key: 'name', // dataIndex์ ์ผ์นํด์ผ ํ๋ฉฐ, dataIndex๊ฐ ์์ผ๋ฉด ๊ตณ์ด ํ์์์ width: 150, render: text => <a>{text}</a>, }, { title: 'Age', dataIndex: 'age', key: 'age', width: 80, }, { title: 'Address', dataIndex: 'address', key: 'address 1', ellipsis: true, }, ]; // data ์ง์ (columns์ dataIndex์ ์ผ์นํด์ผ ํ๋ค) const data = [ { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park, New York No. 1 Lake Park', }, { key: '2', name: 'Jim Green', age: 42, address: 'London No. 2 Lake Park, London No. 2 Lake Park', }, ]; ReactDOM.render( <Table columns={columns} dataSource={data} /> );
antd API๋ฅผ ํ์ฉํด์ ๋ค์ํ ์ปค์คํฐ๋ง์ด์ง์ด ๊ฐ๋ฅํ๋ค.
Table
๋ฐ Column
์ ๋ํ์ ์ธ API์ ์ด๋ฅผ ํ์ฉํ ์์๋ฅผ ๋ค์ด๋ณด์!
// MARK: ์ปฌ๋ผ ์ ํ . const TableColumns:Array<String> = [ { title: 'EMAIL', // ์ ๋ชฉ ํ์ ๋ค์ด๊ฐ๋ ์ด๋ฆ key: 'email', dataIndex: 'email', // ์ค์ data width: '30px', align: 'center', }, { title: 'NAME', key: 'name', dataIndex: 'name', align: 'center', width: '60px', fixed: true, }, { title: t('page.host_list.table.header.created'), key: 'createdAt', dataIndex: 'createdAt', // ํ์ฌ ๋ ์ง์ ๋ณด๋ฅผ ํ๊ธฐํ๋ ์์ฑ width: '140px', align: 'center', // ํน์ ํค:๊ฐ์ returnํ๋๋ก "render ์์ฑ"์ ์ ์ฉํ๋ค. render: (value) => dateFormat(new Date(value), 'simple', language), }, { title: 'OPTION', key: 'option', width: '80px', align: 'center', // ํน์ ํ๊ทธ๋ฅผ returnํ๋๋ก "render ์์ฑ"์ ์ ์ฉํ๋ค. render: (_, record) => { return ( <> <Popconfirm title="๋น๋ฐ๋ฒํธ๋ฅผ ๋ฆฌ์ ํ์๊ฒ ์ต๋๊น?" onConfirm={() => { passwordReset(record) } }> <ResetBtn>๋ฆฌ์ </ResetBtn> </Popconfirm> ) }, }]
โญ๏ธ render ์์ฑ์ 2๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋๋ค.
(value, record)
value ์ธ์๋ฅผ ๋ฐ์ ํ์๊ฐ ์์ผ๋ฉด ์์๋ก'_'
๋ฅผ ๋ฃ์ด์ค ์ ์๋ค.('_', render)
record ์ธ์๋ฅผ ๋ฐ์ ํ์๊ฐ ์์ผ๋ฉด ๊ทธ๋ฅ ์ฒซ๋ฒ์งธ ์ธ์์ธ value๋ง ํ๊ธฐํด๋ ๋จ.์ฒซ ๋ฒ์งธ ์ธ์์ธ value์์๋ ๊ฐ์ฒด ์์ ํน์ ํค:๊ฐ์ ๋ฐ๋๋ค.
์) ์ ์์์์
[
{title:-- , key:--, dataIndex:-- },
{title:-- , key:--, dataIndex:--},
{title:-- , key:--, dataIndex:--}
]
๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
value์ธ์๋ ํด๋น ๊ฐ์ฒด ์์title
๋๋key
๋๋dataIndex
์ ํน์ ํค:๊ฐ์ ์๋ฏธํ ์ ์๋ค.๋ฐ๋ผ์ ์์ value ํค:๊ฐ์
dataIndex: createdAt
์ ์๋ฏธํ๋ฉฐ, ํด๋น value์ ๋ณด๋ก render์ ๋ณํ๊ฐ์ ์ถ๋ ฅํ๋ค.๋ ๋ฒ์งธ ์ธ์์ธ record์์๋ ๋ฐฐ์ด ์์ ํน์ ๊ฐ์ฒด(
{--}
)๋ฅผ ๋ฐ๋๋ค.
์) ์ ์์์์ render์ธ์๋ ํด๋น ๊ฐ์ฒด ์์{--}
๋ฌถ์์ด ๋ ์ ์๋ค.{title:-- , key:--, dataIndex:-- }
๋ฐ๋ผ์ ์์ record ๊ฐ์ ํด๋น ๊ฐ์ฒด ์์ ๋ชจ๋ ํค:๊ฐ์ ์ ์ฉํ๋ฏ๋ก, return ์ผ๋ก ์ถ๋ ฅ๋๋ ๋ด์ฉ์ ๋ชจ๋ ํค:๊ฐ์ ํฌํจํ๋ค.