{"id":23510874,"url":"https://github.com/danielkov/react-data-grid","last_synced_at":"2025-05-13T17:17:39.931Z","repository":{"id":98242269,"uuid":"91692371","full_name":"danielkov/react-data-grid","owner":"danielkov","description":"Data Grid Component for React.","archived":false,"fork":false,"pushed_at":"2017-05-19T14:20:05.000Z","size":276,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-08T22:02:02.673Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielkov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-18T12:46:57.000Z","updated_at":"2017-05-18T12:47:48.000Z","dependencies_parsed_at":"2023-05-18T22:00:26.736Z","dependency_job_id":null,"html_url":"https://github.com/danielkov/react-data-grid","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Freact-data-grid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Freact-data-grid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Freact-data-grid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Freact-data-grid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielkov","download_url":"https://codeload.github.com/danielkov/react-data-grid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253990504,"owners_count":21995776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-25T12:12:41.116Z","updated_at":"2025-05-13T17:17:39.622Z","avatar_url":"https://github.com/danielkov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DataGrid Readme\n\n### Table of Contents\n\n- [Introduction](#introduction)\n- [Usage](#usage)\n- [Testing](#testing)\n- [Development](#development)\n- [Miscellaneous](#miscellaneous)\n\n## Introduction\n\nThis project was bootstrapped with [`react-architect`](https://npmjs.com/package/react-architect), which is another project of mine. If you want to take the hassle out of the setup of component development environments, consider checking it out.\n\nA simple, extendable React Component for displaying data in a grid-style manner. Because performance is key in large applications it is highly recommended to read the [performance](#performance) section.\n\n## Usage\n\nTo use DataGrid install it with `npm`:\n\n```sh\nnpm install --save data-grid\n```\n\nThen include it in the project with:\n\n```js\nimport DataGrid from 'data-grid'\n```\n\nTo render it to the DOM:\n\n```js\nReactDOM.render(\u003cDataGrid/\u003e)\n```\n\n## API\n\nIf you want to get a deeper understanding of how the component works, read the source.\n\n### Props\n\n#### columns: `[ { name: \u003cString\u003e, index: \u003cString\u003e, component: \u003cFunction\u003e } ]`\n\nThis prop is required for displaying anything in the grid. Due to the fact that sometimes even the columns of the grid are dynamically loaded from an outside resouce, none of these props are actually marked as required, which means that 'prop-types' will not warn you if they're left empty.\n\nThe `name` property will show up in the table header, while the `index` property will be used to sort through the data (see below).\n\nA third, `component` property can also be assigned, which will affect the default rendering of the element. If you're using a custom render method for cells, this property will be ignored.\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    columns={[\n      {name: 'Name', index: 'name'},\n      {name: 'Age', index: 'age'},\n      {name: 'Job', index: 'occupation'}\n    ]}\n  /\u003e,\n  root\n)\n```\n\nTaking this further, if you're lazy to type out a name and an index, you could create a function that does it for you, like this:\n\n```js\nconst createColumns = (colNames) =\u003e (\n  colNames.map(name =\u003e ({\n    name: name,\n    index: name.toLowerCase()\n  }))\n)\n```\n\nOf course your names may include other characters, such as whitespace that can't be passed down as JSON from your back-end, for which case you can actually use some helper functions to turn these into JSON-compatible object keys.\n\n#### data: `[ \u003cObject\u003e ]`\n\nThis prop should be an Array of objects, because this is what the grid uses to figure out what you want to display. The default render function will go through this array and sort the objects according to the `columns` prop. This means that only data that has a header will be displayed in the table and each value will fall under its designated table header.\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    {...previous}\n    data={[\n      {name: 'Sam', age: 50, occupation: 'dentist'},\n      {name: 'Daniel', age: 21, occupation: 'web-designer'},\n      {name: 'Joe', age: 42, occupation: 'lawyer'},\n    ]}\n  /\u003e,\n  root\n)\n```\n\nAssuming that you're following this along as a getting started guide, you will have already added `columns` prop to your component. If you like copy-pasting example code, just save your props in an object, called `previous` once you understand what they do.\n\nSay you had some other properties on one or many of the objects in your data array. The grid would just ignore those. If you want those included also, just add them to the columns by their index.\n\n#### onRowClick: `\u003cFunction\u003e`\n\nThis function gets called with the original event as its parameter when a row gets clicked.\n\nThis is not a fully reasonable feature as of yet. It would be desirable to bind this function to each of the `Cell` components, so that the function scope will be useful, however I did not find this to be worth the performance trade-offs for this raw component.\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    {...previous}\n    onRowClick={console.log}\n  /\u003e\n)\n```\n\nThe above example will log the default React Synthetic event emitted by the row that was clicked.\n\n#### onCellClick: `\u003cFunction\u003e`\n\nThis function gets called with the original event as its parameter when a cell gets clicked\n\nAs said about the previous feature, this one is also not reasonably implemented. You can use it anyway to get information about which cell the user clicked. Note that unless you stop bubbling, each time a cell is clicked, a row click event will also be fired.\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    {...previous}\n    onCellClick={console.log}\n  /\u003e\n)\n```\n\n#### headerStyle: `\u003cObject\u003e`\n\nThis is a regular React style object that will be passed on to the table header upon rendering. Use this to add important inline styles to your table header.\n\n#### headerCellStyle: `\u003cObject\u003e`\n\nThis is a regular React style object that will be passed on to each table header cell upon rendering. Use this to add important inline styles to your table header cells.\n\n#### rowStyle: `\u003cObject\u003e`\n\nThis is a regular React style object that will be passed on to each row upon rendering. Use this to add important inline styles to your table rows.\n\n#### cellStyle: `\u003cObject\u003e`\n\nThis is a regular React style object that will be passed on to each cell upon rendering. Use this to add important inline styles to your table cells.\n\n#### headerClassName: `\u003cString\u003e`\n\nThis is a string that will be passed on to the React prop: `className` upon rendering the table header.\n\n#### headerCellClassName: `\u003cString\u003e`\n\nThis is a string that will be passed on to the React prop: `className` upon rendering each table header cell.\n\n#### cellClassName: `\u003cString\u003e`\n\nThis is a string that will be passed on to the React prop: `className` upon rendering each table cell.\n\n#### rowClassName: `\u003cString\u003e`\n\nThis is a string that will be passed on to the React prop: `className` upon rendering each table row.\n\n#### renderRow: `\u003cFunction ( data: \u003cArray\u003e, index: \u003cNumber\u003e )\u003e`\n\nThis is a function that can be used to take place of the default grid row rendering function. If you want to control how each row gets displayed, e.g.: only render rows conditionally (and for some reason you want to do this in the component itself, instead of doing it in the data you provide), this is the way you can do it.\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    {...previous}\n    renderRow={(data, i) =\u003e (\u003cMyCustomRow key={i} data={data}/\u003e)}\n  /\u003e\n)\n```\n\nDon't forget to add a unique key prop, otherwise React will scream at you when using development builds.\n\n**Beware:** this will override the default cell rendering too, since that's being taken care of by a component called `\u003cDataGridRow/\u003e`. If you want to preserve cell rendering, but perhaps want to add a wrapper around each row, you can do so, by actually using the aforementioned component itself. Do remember though, that `\u003cDataGrid/\u003e` will no longer pass down props that are related to rows or cells (these all conveniently have the word 'row' or 'cell' in them), so you'll have to add those manually. Read the documentation for this component below.\n\nExample:\n\n```js\nimport DataGrid, { DataGridRow } from 'data-grid'\n\nrender(\n  \u003cDataGrid\n    {...previous}\n    renderRow={(data, i) =\u003e \u003cMyWrapper\u003e\u003cDataGridRow {...otherProps} key={i} data={data}/\u003e\u003c/MyWrapper\u003e}\n  /\u003e\n)\n```\n\n#### renderCell: `\u003cFunction ( data: { value: \u003cString|Number\u003e, component: \u003cFunction\u003e }, index: \u003cNumber\u003e )\u003e`\n\nExample:\n\n```js\nrender(\n  \u003cDataGrid\n    {...previous}\n    renderCell={(data, i) =\u003e (\u003cMyCustomCell key={i}\u003edata.value\u003c/MyCustomCell\u003e)}\n  /\u003e\n)\n```\n\nDo note that if you override the default cell rendering this way, some props, like the ones that have the word 'cell' in them will no longer be considered by the component. This also includes the `component` property of the `columns` prop. If you'd like to keep those, you can always just implement them yourself, but at that point you're already rendering your own component instead of a cell anyway, so it is rather pointless.\n\nKeep in mind also that it is only schemantically appropriate if you use table data tags (`\u003ctd\u003e`) somewhere in your markup when rendering table data.\n\nFor performance reasons, do not forget to include the `key` prop on your custom cells, as these will get rendered in a loop.\n\n### Exports\n\n#### default: `\u003cDataGrid/\u003e`\n\nUse example:\n\n```js\nimport DataGrid from 'data-grid'\nimport { render } from 'react-dom'\n\nrender(\u003cDataGrid/\u003e, root)\n```\n\n#### `\u003cDataGridRow/\u003e`\n\nUse example:\n\n```js\nimport { DataGridRow } from 'data-grid'\nimport { render } from 'react-dom'\n\nrender(\u003cDataGridRow/\u003e, root)\n```\n\n#### `\u003cDataGridHeader/\u003e`\n\nUse example:\n\n```js\nimport { DataGridHeader } from 'data-grid'\nimport { render } from 'react-dom'\n\nrender(\u003cDataGridHeader/\u003e, root)\n```\n\n#### `defaultStyles`\n\nBeing a UX designer at heart, I couldn't write a component that looks as disappointing as the default formatting of a table. This is why I included some sane default styles that you can use for your table component if you need it for a demo, or just can't think of a way to make it look better. These are not added to the table by default, because rendering inline styles on each cell actually has some tolls on performance and painting / repainting (even with these minimal inline styles it runs about 50% slower). If you like them, turn them into CSS and use it with classes. Read more about this under [performance](#performance).\n\nExample:\n\n```js\nimport { defaultStyles as styles } from 'data-grid'\n\nrender(\n  \u003cDataGrid\n    {...setup}\n    style={styles.table}\n    cellStyle={styles.cell}\n    rowStyle={styles.row}\n    headerCellStyle={styles.cell}\n    headerStyle={styles.header}\n  /\u003e\n)\n```\n\n## Performance\n\nIn real-world applications component performance is key in delivering a smooth User Experience. This data grid is especially useful for displaying large sets of data and as such it is expected to be used in applications that manage massive amounts of data. This component uses `React.PureComponent` under the hood. If you do not understand the implications of this, make sure you read the [official documentation](https://facebook.github.io/react/docs/react-api.html#react.purecomponent) on this.\n\nWhile this component aims to be a minimal API for more complex grids to be built upon it, it does have some heavy logic while rendering cell data, more specifically as it selects which properties / values it should display and where. While this may put some strain on slower computers, when trying to render data sets of 10+ columns with over 1000 rows, it really is a worthwhile trade-off, as it allows you to be more flexible with your data. To get a render of more than a second on my (super)computer it took 10 columns and around 4000 rows, which is insane and should never ideally happen in real applications.\n\nAll that said, here are my tips to increase performance of the data grid in your application:\n\n1. When using custom rendering, make sure you always add that `key` prop.\n  - React will warn you about this when running in a development environment, however I am also warning you here. React needs that internally to faster select DOM Nodes for diffing.\n\n2. Whenever possible, for styling, use CSS - as intended, rather than inline JS-based styles.\n  - CSS was invented for this kind of stuff and is faster and better at doing styles.\n  - It is also cleaner if you use stylesheets. Makes it easier to debug, change in browser, etc.\n\n3. Decouple data logic from components, e.g.: Redux, Flux, MobX (or some other X).\n  - While this may not necessarily be a performance improvement (it most likely will be), but decoupling logic from the UI makes it tons easier to work on larger scale applications.\n  - Some of the frameworks mentioned above take some optimization steps to make your code run faster. React does little of this. It focuses on DOM manipulation instead, which is what it should mainly be used for.\n\n4. Use Higher Order Components (HOCs) when extending this grid.\n  - HOCs are cool in that they wrap existing elements while keeping their API in-tact and also adding extra functionality.\n\n5. Avoid renders whenever possible.\n  - The grid extends `PureComponent`, which already compares props before doing a re-render, however it can't dive into your data, instead it does shallow comparison. E.g.: `[] !== []`, since objects (and so arrays too) are passed by reference, not value.\n  - Implement some comparing logic of your own, in your logic layer to avoid unnecessary re-renders. If the data does not change, do not pass it again as props.\n  - Also note that mutating the prop and passing the same one again, will not trigger a re-render, which may be bad for you if you did want a re-render. To stop that from happening, you could always pass in new data in your props, rather than mutating the previous one.\n\n## Testing\n\nTo test DataGrid locate the root folder and run tests with:\n\n```sh\nnpm test\n```\n\nTest output and coverage will be shown in standard output.\n\nIf you change something that **should** affect the appearance of your component (e.g.: in the beginning of development), run `npm test` with flags to override snapshots.\n\n```sh\nnpm test -- -u\n```\n\nThis will update the snapshot. Make sure you do this when you need the component to change appearance and behavior.\n\n## Development\n\nTo begin development, first install dependencies with:\n\n```sh\nnpm install\n```\n\n**NOTE:** if tests fail due to not found dependencies (`cannot resolve...`) run the install again with:\n\n```sh\nnpm install --dev-only\n```\n\nTo start the development environment, type in your shell:\n\n```sh\nnpm start\n```\n\nThis will initialize Storybook, which is a great tool for developing and proof-testing your components on the go.\n\nMake sure you update this `README`, the `CHANGELOG` with important changes you've made.\n\nTo publish the package update `package.json` with the desired new version. Packages use [semver](http://semver.org/).\n\nA quick way to update the `package.json` is using [`npm`](https://docs.npmjs.com/cli/version).\n\nThen switch to using private repository (if not already):\n\n```sh\nnpm set registry \u003curl of registry\u003e\n```\n\nNow you can publish with:\n\n```sh\nnpm publish\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielkov%2Freact-data-grid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielkov%2Freact-data-grid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielkov%2Freact-data-grid/lists"}