본문 바로가기
개발/리액트

리액트 fetch() 함수를 이용한 데이터 조회 및 테이블 컴포넌트를 이용한 출력

by ^..^v 2020. 5. 19.
728x90
반응형

#1 프로젝트 생성

C:\> npx create-react-app react

 

 

#2 SearchGithub.js 파일 생성

fetch() 함수를 이용해서 깃허브 검색 결과를 받아와서 테이블 형태로 화면에 출력

import React, { useState } from 'react';
import './App.css';

function SearchGithub() {
    const [data, setData] = useState([]);
    const [keyword, setKeyword] = useState('');

    const fetchData = () => {
        const url = `https://api.github.com/search/repositories?q=${keyword}`;
        fetch(url)
            .then(response => response.json())
            .then(responseData => { setData(responseData.items); });
    }

    const handleChange = (e) => {
        setKeyword(e.target.value);
    }

    const tableRows = data.map(
        (item, index) =>
            <tr key={index}>
                <td>{item.full_name}</td>
                <td><a href={item.html_url}>{item.html_url}</a></td>
            </tr>
    );

    return (
        <div>
        <div>
            <h1>github 검색</h1>
        </div>
        <div className="App">
            <input type="text" onChange={handleChange} />
            <button onClick={fetchData} value={keyword} >검색</button>
            <table><tbody>{tableRows}</tbody></table>
        </div>
        </div>
    );
}

export default SearchGithub;

 

#3 App.js에 SearchGithub.js 추가

import React from 'react';
import './App.css';
import SearchGitHub from './SearchGithub.js';

function App() {
  return (
    <div className="App">
      <SearchGitHub />
    </div>
  );
}

export default App;

 

#4 웹 브라우저를 통해서 확인

c:\react_project> npm start

 

#5 유용한 서브 파티 리액트 컴포넌트를 검색

https://js.coach/

https://github.com/brillout/awesome-react-components

 

brillout/awesome-react-components

Curated List of React Components & Libraries. Contribute to brillout/awesome-react-components development by creating an account on GitHub.

github.com

 

테이블 기능을 제공하는 컴포넌트 추가

c:\react_project> npm install react-table

C:\react_project> npm install styled-components

 

[참고]

https://www.npmjs.com/package/react-table

https://styled-components.com/

 

styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress 💅

styled-components.com

 

#6 react-table paging 기능 추가

[참고] https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination?file=/src/App.js:26-64

 

tannerlinsley/react-table: pagination - CodeSandbox

tannerlinsley/react-table: pagination using namor, react, react-dom, react-scripts, react-table, styled-components

codesandbox.io

import React, { useState } from 'react';
import styled from 'styled-components'
import { useTable, usePagination } from 'react-table'

const Styles = styled.div`
  padding: 1rem;

  table {
    border-spacing: 0;
    border: 1px solid black;
    tr {
      :last-child {
        td { border-bottom: 0; }
      }
    }
    th, td {
      margin: 0;
      padding: 0.5rem;
      border-bottom: 1px solid black;
      border-right: 1px solid black;
      :last-child { border-right: 0; }
    }
  }
  .pagination { padding: 0.5rem; }
`;

function Table({ columns, data }) {
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        prepareRow,
        page,
        canPreviousPage,
        canNextPage,
        pageOptions,
        pageCount,
        gotoPage,
        nextPage,
        previousPage,
        setPageSize,
        state: { pageIndex, pageSize },
    } = useTable(
        {
            columns,
            data,
            initialState: { pageIndex: 1 },
        },
        usePagination
    )

    return (
        <>
            <table {...getTableProps()}>
                <thead>
                    {headerGroups.map(headerGroup => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map(column => (
                                <th {...column.getHeaderProps()}>{column.render('Header')}</th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {page.map((row, i) => {
                        prepareRow(row)
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>
            <div className="pagination">
                <button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
                    {'<<'}
                </button>{' '}
                <button onClick={() => previousPage()} disabled={!canPreviousPage}>
                    {'<'}
                </button>{' '}
                <button onClick={() => nextPage()} disabled={!canNextPage}>
                    {'>'}
                </button>{' '}
                <button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
                    {'>>'}
                </button>{' '}
                <span>
                    Page{' '}
                    <strong>
                        {pageIndex + 1} of {pageOptions.length}
                    </strong>{' '}
                </span>
                <span>
                    | Go to page:{' '}
                    <input
                        type="number"
                        defaultValue={pageIndex + 1}
                        onChange={e => {
                            const page = e.target.value ? Number(e.target.value) - 1 : 0
                            gotoPage(page)
                        }}
                        style={{ width: '100px' }}
                    />
                </span>{' '}
                <select
                    value={pageSize}
                    onChange={e => {
                        setPageSize(Number(e.target.value))
                    }}
                >
                    {[10, 20, 30, 40, 50].map(pageSize => (
                        <option key={pageSize} value={pageSize}>
                            Show {pageSize}
                        </option>
                    ))}
                </select>
            </div>
        </>
    )
}

function SearchGithub() {
    const [data, setData] = useState([]);
    const [keyword, setKeyword] = useState('');

    const fetchData = () => {
        const url = `https://api.github.com/search/repositories?q=${keyword}`;
        fetch(url)
            .then(response => response.json())
            .then(responseData => { setData(responseData.items); });
    }

    const handleChange = (e) => {
        setKeyword(e.target.value);
    }

    const btnClick = (value) => {
        alert(value);
    }

    const columns = [{
        Header: '이름',
        accessor: 'full_name'
    }, {
        Header: 'URL',
        accessor: 'html_url',
    }, {
        Header: '소유자',
        accessor: 'owner.login',
    }, {
        id: 'button',
        sortable: false,
        filterable: false,
        width: 100,
        accessor: 'full_name',
        Cell: ({ value }) => (<button onClick={() => { btnClick(value) }}>Press me</button>)
    }]

    return (
        <Styles>
            <input type="text" onChange={handleChange} />
            <button onClick={fetchData} value={keyword} >조회</button>
            <Table data={data} columns={columns} filterable={true} defaultPageSize={10} />
        </Styles>
    );

}

export default SearchGithub;

 

#7 브라우저를 통해 확인

 

728x90
반응형

댓글