react antd table functional component , 검색, 필터, 체크박스 구현

Mori·2021년 12월 9일
1

개발

목록 보기
2/5
post-thumbnail

Antd Table에 불러온 데이터를 적용시켜보자.

antd 예제는 class형 컴포넌트로 되어 있다.
나는 이것을 함수형 컴포넌트로 바꾸었다.

  • sort기능과 필터기능을 적용 시켰다.
  • 체크 박스를 적용시키려면, key가 필요하다. keyArr이라는 함수를 만들어 각각의 항목에 key값을 만들어 주었다.

참고 : Highlighter는 npm으로 설치할 필요 없이, import구문만 적어주면 된다.

import React, { useState,useEffect, useRef } from 'react';
import { Table, Button, Space, Input } from 'antd';
import Styles from "../../scss/App.module.scss";
import { Link, useLocation, useHistory  } from 'react-router-dom';
import ReactDOM from "react-dom";
import Highlighter from "react-highlight-words";
import { SearchOutlined } from '@ant-design/icons';


import * as apiUserGoods from '../../lib/apiUserGoods';
import * as net from '../../lib/network';


const TOKEN = net.TOKEN;

const UserServiceHistory = () => {
    const [ goodsView, setGoodsView ] = useState();

    // 체크박스를 쓰려면 이 코드가 필요하다.
    const [select, setSelect] = useState({
        selectedRowKeys: [],
        loading: false,
    });
    const { selectedRowKeys, loading } = select;
    const rowSelection = {
        selectedRowKeys,
        onChange: (selectedRowKeys) => {
            setSelect({...select,selectedRowKeys});
        }
    };
    /////

    
    const [searchText, setSearchText] = useState('');
    const [searchedColumn, setSearchedColumn] = useState('');
    const searchInput = useRef(null);
    const [state, setState] = useState({searchText:'', searchedColumn:''})




    const getColumnSearchProps = dataIndex => ({
        filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
            <div style={{ padding: 8 }}>
              <Input
                ref={searchInput}
                placeholder={`Search ${dataIndex}`}
                value={selectedKeys[0]}
                onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
                style={{ marginBottom: 8, display: 'block' }}
              />
              <Space>
                <Button
                  type="primary"
                  onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
                  icon={<SearchOutlined />}
                  size="small"
                  style={{ width: 90 }}
                >
                  Search
                </Button>
                <Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
                  Reset
                </Button>
                <Button
                  type="link"
                  size="small"
                  onClick={() => {
                    confirm({ closeDropdown: false });
                    searchText(selectedKeys[0]);
                    searchedColumn(dataIndex);
                  }}
                >
                  Filter
                </Button>
              </Space>
            </div>
          ),
          filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
          onFilter: (value, record) =>
            record[dataIndex]
              ? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
              : '',
          onFilterDropdownVisibleChange: visible => {
            if (visible) {
              setTimeout(
                  () => searchInput && searchInput.current && searchInput.current.select()
                )
            }
          },
          render: text =>
            searchedColumn === dataIndex ? (
              <Highlighter
                highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
                searchWords={[searchText]}
                autoEscape
                textToHighlight={text ? text.toString() : ''}
              />
            ) : (
              text
            ),
    })

    const handleSearch = (selectedKeys, confirm, dataIndex) => {
        confirm();
        setState({
          searchText: selectedKeys[0],
          searchedColumn:dataIndex,
        });
    };
    
    function handleReset (clearFilters) {
        clearFilters();
        setState({ searchText: '' });
      };

    function onChange(pagination, filters, sorter, extra) {
      console.log('params', pagination, filters, sorter, extra);
    }

//useEffect를 이용하여 필요한 데이터를 받아온다.
    useEffect(()=>{
        apiUserGoods.getUserGoodsHistoryList()
        .then(result=>{
            // console.log('받아온 데이터',result)
            const keyArr = result.data.data.map((data,index)=>{
                return{
                    count: data.count,
                    docSeq: data.docSeq,
                    endDttm: data.endDttm,
                    goodsSeq: data.goodsSeq,
                    historySeq: data.historySeq,
                    regDttm: data.regDttm,
                    startDttm: data.startDttm,
                    sellingPrice: data.sellingPrice,
                    userEmail: data.userEmail,
                    userSeq: data.userSeq,
                    key:index //꼭 key가 필요하다!
                }
            })
            setGoodsView(keyArr)
        }).catch(error=>{
            console.log('에러',error)
            }
        )
    }, [setGoodsView]);
    const columns = [
      
        {
            title: 'userSeq',
            dataIndex: 'userSeq',
            key: 'userSeq',
            sorter: (a, b) => a.userSeq - b.userSeq, //sort기능을 해준다
            ...getColumnSearchProps('userSeq'), //검색이 가능하게 해준다

        },
        {
            title: 'userEmail',
            dataIndex: 'userEmail',
            key: 'userEmail',    
        },
        {
            title: 'count',
            dataIndex: 'count',
            key: 'count',     
            
            // defaultSortOrder: 'descend',
            sorter: (a, b) => a.count - b.count,
            ...getColumnSearchProps('count'),

        },
        {
            title: 'docSeq',
            dataIndex: 'docSeq',
            key: 'docSeq',  
            sorter: (a, b) => a.docSeq - b.docSeq,
        },
        {
            title: 'sellingPrice',
            dataIndex: 'sellingPrice',
            key: 'sellingPrice',
            sorter: (a, b) => a.sellingPrice - b.sellingPrice,

        },
        {
            title: 'startDttm',
            dataIndex: 'startDttm',
            key: 'startDttm',
            sorter: (a, b) => a.startDttm - b.startDttm,

        },
        {
            title: 'regDttm',
            dataIndex: 'regDttm',
            key: 'regDttm',
            sorter: (a, b) => a.regDttm - b.regDttm,

        },
        {
            title: 'endDttm',
            dataIndex: 'endDttm',
            key: 'endDttm',
            sorter: (a, b) => a.endDttm - b.endDttm,

        },
        {
            title:'goodsSeq',
            dataIndex:'goodsSeq',
            key:'goodsSeq',
            sorter: (a, b) => a.goodsSeq - b.goodsSeq,
            ...getColumnSearchProps('goodsSeq'),


        },
        {
            title:'historySeq',
            dataIndex:'historySeq',
            key:'historySeq',
            sorter: (a, b) => a.historySeq - b.historySeq,
            ...getColumnSearchProps('historySeq'),


        }
        // {
        //   title: 'Action',
        //   dataIndex: '',
        //   key: 'x',
        //   render: (publicView) => <a onClick={publicDelete.bind(this, publicView.researchId)}>Delete</a>,
        // },
      ]; 

    
    return (
        <div className={Styles.page_wrap}>
        <h2 className={Styles.admin_title}>Product Service History</h2>
        <p className={Styles.admin_txt}>상품 서비스 가입 및 Credit 추가건에 대한 히스토리 목록을 조회한다.</p>               
        <Table
            columns={columns}
            rowSelection={rowSelection}

            dataSource={goodsView}
            loading={loading}
            onChange={onChange}
            pagination={{pageSize:20}}

        />
        <Button type="primary" className={Styles.admin_btn_margin}>
          <Link to="/HomepagePublicationsRegist">추가</Link></Button>
        {/* <Button onClick={publicDelete} type="primary" danger >
          선택삭제
        </Button>    */}
    </div>
    )
}

export default UserServiceHistory;

누군가에게 도움이 되길!

2개의 댓글

comment-user-thumbnail
2022년 4월 15일

감사합니다!!!! 완전 도움 되었어요 ㅠㅠㅠㅠㅠ

1개의 답글