mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 16:30:21 +00:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e6952db93 | ||
|
|
ac43ef2e38 | ||
|
|
9de699bfd3 | ||
|
|
38d82a0397 | ||
|
|
863bf50206 | ||
|
|
492ba8a4f9 | ||
|
|
e0ad323bd8 | ||
|
|
c1e4fb8956 | ||
|
|
1ac1d99f23 | ||
|
|
e5b991751a | ||
|
|
8dc6559e64 | ||
|
|
2955335df1 | ||
|
|
8c090a734b | ||
|
|
439ebad063 | ||
|
|
2ef6e13657 | ||
|
|
6338b32bd8 | ||
|
|
67544d33ff |
+7
-7
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"dist/index.js": {
|
||||
"bundled": 100428,
|
||||
"minified": 47447,
|
||||
"gzipped": 12338
|
||||
"bundled": 103833,
|
||||
"minified": 48853,
|
||||
"gzipped": 12789
|
||||
},
|
||||
"dist/index.es.js": {
|
||||
"bundled": 99612,
|
||||
"minified": 46722,
|
||||
"gzipped": 12193,
|
||||
"bundled": 102990,
|
||||
"minified": 48103,
|
||||
"gzipped": 12638,
|
||||
"treeshaked": {
|
||||
"rollup": {
|
||||
"code": 80,
|
||||
"import_statements": 21
|
||||
},
|
||||
"webpack": {
|
||||
"code": 8457
|
||||
"code": 8444
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
## 7.0.0-rc.6
|
||||
|
||||
- The `columnsBeforeHeaderGroups` and `columnsBeforeHeaderGroupsDeps` hooks have been renamed to `flatColumns` and `flatColumnsDeps` respectively, which better reflects what they are used for, rather than their order, which can remain implicit.
|
||||
- Added `headerGroups` and `headerGroupDeps` hooks, which, similar to `flatColumns`, allow you to decorate (and trigger) the memoized header group generation.
|
||||
- Added `columns` and `columnsDeps` hooks, which, similar to `flatColumns` and `headerGroups`, allow you to decorate (and trigger) the memoized column generation/decoration.
|
||||
- The new hook order is as follows: `columns/columnsDeps` => `flatColumns/flatColumnsDeps` => `headerGroups/headerGroupsDeps`
|
||||
- `useColumnVisibility` now uses the new `headerGroupsDeps` hook to trigger header group regeneration when visibility changes
|
||||
|
||||
## 7.0.0-rc.5
|
||||
|
||||
- Fixed an issue where the exported `useAsyncDebounce` method would crash if its promise throw an error.
|
||||
|
||||
## 7.0.0-rc.4
|
||||
|
||||
- A maintenance release, purely intended to update the @latest tag (which was overwritten by a v6 publish)
|
||||
|
||||
## 7.0.0-rc.3
|
||||
|
||||
- Fixed an issue where `column.clearSortBy` would crash
|
||||
|
||||
## 7.0.0-rc.2
|
||||
|
||||
- `reducerHandlers` has been deprecated in favor of the new `stateReducers` hook.
|
||||
|
||||
@@ -35,7 +35,7 @@ The following options are supported via the main options object passed to `useTa
|
||||
- When `true`, the `expanded` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](../faq.md#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
### Instance Properties
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@ The following options are supported via the main options object passed to `useTa
|
||||
- Must be **memoized**
|
||||
- Allows overriding or adding additional filter types for columns to use. If a column's filter type isn't found on this object, it will default to using the built-in filter types.
|
||||
- For more information on filter types, see Filtering
|
||||
- `getResetFiltersDeps: Function(instance) => [...useEffectDependencies]`
|
||||
- Optional
|
||||
- Defaults to `false`
|
||||
- If set, the dependencies returned from this function will be used to determine when the effect to reset the `filters` state is fired.
|
||||
- `autoResetFilters: Boolean`
|
||||
- Defaults to `true`
|
||||
- When `true`, the `filters` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
|
||||
+23
-25
@@ -28,6 +28,29 @@ useTable({
|
||||
|
||||
> **It's important that the state override is done within a `useMemo` call to prevent the state variable from changing on every render. It's also extremely important that you always use the `state` in any dependencies to ensure that you do not block normal state updates.**
|
||||
|
||||
## How can I use the table state to fetch new data?
|
||||
|
||||
When managing your data externally or asynchronously (eg. server-side pagination/sorting/grouping/etc), you will need to fetch new data as the internal table state changes. With React Hooks, this is fantastically easier than it was before now that we have the `React.useEffect` hook. We can use this hook to "watch" the table state for specific changes and use those effects to trigger fetches for new data (or synchronize any other state you may be managing externally from your table component):
|
||||
|
||||
```js
|
||||
function Table({ data, onFetchData }) {
|
||||
const {
|
||||
state: { pageIndex, pageSize, sortBy, filters },
|
||||
} = useTable({
|
||||
data,
|
||||
})
|
||||
|
||||
// When the these table states change, fetch new data!
|
||||
React.useEffect(() => {
|
||||
onFetchData({ pageIndex, pageSize, sortBy, filters })
|
||||
}, [fetchData, pageIndex, pageSize, sortBy, filters])
|
||||
|
||||
return </>
|
||||
}
|
||||
```
|
||||
|
||||
Using this approach, you can respond and trigger any type of side-effect using the table instance!
|
||||
|
||||
## How can I debounce rapid table state changes?
|
||||
|
||||
React Table has a few built-in side-effects of it's own (most of which are meant for resetting parts of the state when `data` changes). By default, these state side-effects are on and when their conditions are met, they immediately fire off actions that will manipulate the table state. Sometimes, this may result in multiple rapid rerenders (usually just 2, or one more than normal), and could cause any side-effects you have watching the table state to also fire multiple times in-a-row. To alleviate this edge-case, React Table exports a `useAsyncDebounce` function that will allow you to debounce rapid side-effects and only use the latest one.
|
||||
@@ -58,29 +81,6 @@ function Table({ data, onFetchData }) {
|
||||
}
|
||||
```
|
||||
|
||||
## How can I use the table state to fetch new data?
|
||||
|
||||
When managing your data externally or asynchronously (eg. server-side pagination/sorting/grouping/etc), you will need to fetch new data as the internal table state changes. With React Hooks, this is fantastically easier than it was before now that we have the `React.useEffect` hook. We can use this hook to "watch" the table state for specific changes and use those effects to trigger fetches for new data (or synchronize any other state you may be managing externally from your table component):
|
||||
|
||||
```js
|
||||
function Table({ data, onFetchData }) {
|
||||
const {
|
||||
state: { pageIndex, pageSize, sortBy, filters },
|
||||
} = useTable({
|
||||
data,
|
||||
})
|
||||
|
||||
// When the these table states change, fetch new data!
|
||||
React.useEffect(() => {
|
||||
onFetchData({ pageIndex, pageSize, sortBy, filters })
|
||||
}, [fetchData, pageIndex, pageSize, sortBy, filters])
|
||||
|
||||
return </>
|
||||
}
|
||||
```
|
||||
|
||||
Using this approach, you can respond and trigger any type of side-effect using the table instance!
|
||||
|
||||
## How do I stop my table state from automatically resetting when my data changes?
|
||||
|
||||
Most plugins use state that _should_ normally reset when the data sources changes, but sometimes you need to suppress that from happening if you are filtering your data externally, or immutably editing your data while looking at it, or simply doing anything external with your data that you don't want to trigger a piece of table state to reset automatically.
|
||||
@@ -119,5 +119,3 @@ useTable({
|
||||
```
|
||||
|
||||
Now, when we update our data, the above table states will not automatically reset!
|
||||
|
||||
<!-- ## How can I hide/show columns? -->
|
||||
|
||||
@@ -3652,16 +3652,16 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3:
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^1.3.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c"
|
||||
integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
|
||||
integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
|
||||
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
|
||||
eslint@^5.16.0:
|
||||
version "5.16.0"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "7.0.0-rc.2",
|
||||
"version": "7.0.0-rc.6",
|
||||
"description": "Hooks for building lightweight, fast and extendable datagrids for React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
|
||||
@@ -1,4 +1,34 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1575859193604,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21589,
|
||||
"delta": 563
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575690248030,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21026,
|
||||
"delta": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575675308812,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21025,
|
||||
"delta": -421
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575620433902,
|
||||
"files": [
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1575859200604,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 21403,
|
||||
"delta": 561
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575675317538,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 20842,
|
||||
"delta": -383
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575620442742,
|
||||
"files": [
|
||||
|
||||
@@ -19,7 +19,7 @@ export const useColumnVisibility = hooks => {
|
||||
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => [
|
||||
hooks.headerGroupsDeps.push((deps, instance) => [
|
||||
...deps,
|
||||
instance.state.hiddenColumns,
|
||||
])
|
||||
|
||||
+81
-33
@@ -49,8 +49,12 @@ export const useTable = (props, ...plugins) => {
|
||||
data,
|
||||
hooks: {
|
||||
stateReducers: [],
|
||||
columnsBeforeHeaderGroups: [],
|
||||
columnsBeforeHeaderGroupsDeps: [],
|
||||
columns: [],
|
||||
columnsDeps: [],
|
||||
flatColumns: [],
|
||||
flatColumnsDeps: [],
|
||||
headerGroups: [],
|
||||
headerGroupsDeps: [],
|
||||
useInstanceBeforeDimensions: [],
|
||||
useInstance: [],
|
||||
useRows: [],
|
||||
@@ -117,58 +121,102 @@ export const useTable = (props, ...plugins) => {
|
||||
dispatch, // The resolved table state
|
||||
})
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumns = useConsumeHookGetter(instanceRef.current.hooks, 'columns')
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsDeps = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'columnsDeps'
|
||||
)
|
||||
|
||||
// Decorate All the columns
|
||||
let columns = React.useMemo(
|
||||
() => decorateColumnTree(userColumns, defaultColumn),
|
||||
[defaultColumn, userColumns]
|
||||
() =>
|
||||
applyHooks(
|
||||
getColumns(),
|
||||
decorateColumnTree(userColumns, defaultColumn),
|
||||
instanceRef.current
|
||||
),
|
||||
[
|
||||
defaultColumn,
|
||||
getColumns,
|
||||
userColumns,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getColumnsDeps(instanceRef.current),
|
||||
]
|
||||
)
|
||||
|
||||
instanceRef.current.columns = columns
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getFlatColumns = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'flatColumns'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsBeforeHeaderGroups = useConsumeHookGetter(
|
||||
const getFlatColumnsDeps = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'columnsBeforeHeaderGroups'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsBeforeHeaderGroupsDeps = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'columnsBeforeHeaderGroupsDeps'
|
||||
'flatColumnsDeps'
|
||||
)
|
||||
|
||||
// Get the flat list of all columns and allow hooks to decorate
|
||||
// those columns (and trigger this memoization via deps)
|
||||
let flatColumns = React.useMemo(() => {
|
||||
let newColumns = applyHooks(
|
||||
getColumnsBeforeHeaderGroups(),
|
||||
flattenBy(columns, 'columns'),
|
||||
instanceRef.current
|
||||
)
|
||||
let flatColumns = React.useMemo(
|
||||
() =>
|
||||
applyHooks(
|
||||
getFlatColumns(),
|
||||
flattenBy(columns, 'columns'),
|
||||
instanceRef.current
|
||||
),
|
||||
[
|
||||
columns,
|
||||
getFlatColumns,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getFlatColumnsDeps(instanceRef.current),
|
||||
]
|
||||
)
|
||||
|
||||
return newColumns
|
||||
}, [
|
||||
columns,
|
||||
getColumnsBeforeHeaderGroups,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getColumnsBeforeHeaderGroupsDeps(),
|
||||
])
|
||||
instanceRef.current.flatColumns = flatColumns
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderGroups = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'headerGroups'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderGroupsDeps = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'headerGroupsDeps'
|
||||
)
|
||||
|
||||
// Make the headerGroups
|
||||
const headerGroups = React.useMemo(
|
||||
() => makeHeaderGroups(flatColumns, defaultColumn),
|
||||
[defaultColumn, flatColumns]
|
||||
() =>
|
||||
applyHooks(
|
||||
getHeaderGroups(),
|
||||
makeHeaderGroups(flatColumns, defaultColumn),
|
||||
instanceRef.current
|
||||
),
|
||||
[
|
||||
defaultColumn,
|
||||
flatColumns,
|
||||
getHeaderGroups,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getHeaderGroupsDeps(),
|
||||
]
|
||||
)
|
||||
|
||||
instanceRef.current.headerGroups = headerGroups
|
||||
|
||||
const headers = React.useMemo(
|
||||
() => (headerGroups.length ? headerGroups[0].headers : []),
|
||||
[headerGroups]
|
||||
)
|
||||
|
||||
Object.assign(instanceRef.current, {
|
||||
columns,
|
||||
flatColumns,
|
||||
headerGroups,
|
||||
headers,
|
||||
})
|
||||
instanceRef.current.headers = headers
|
||||
|
||||
// Access the row model
|
||||
const [rows, flatRows] = React.useMemo(() => {
|
||||
|
||||
@@ -8,10 +8,10 @@ actions.setColumnOrder = 'setColumnOrder'
|
||||
|
||||
export const useColumnOrder = hooks => {
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => {
|
||||
hooks.flatColumnsDeps.push((deps, instance) => {
|
||||
return [...deps, instance.state.columnOrder]
|
||||
})
|
||||
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
|
||||
hooks.flatColumns.push(flatColumns)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ function reducer(state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
function columnsBeforeHeaderGroups(columns, instance) {
|
||||
function flatColumns(columns, instance) {
|
||||
const {
|
||||
state: { columnOrder },
|
||||
} = instance
|
||||
|
||||
@@ -42,7 +42,7 @@ function reducer(state, action) {
|
||||
const { path, expanded } = action
|
||||
const key = path.join('.')
|
||||
const exists = state.expanded.includes(key)
|
||||
const shouldExist = typeof set !== 'undefined' ? expanded : !exists
|
||||
const shouldExist = typeof expanded !== 'undefined' ? expanded : !exists
|
||||
let newExpanded = new Set(state.expanded)
|
||||
|
||||
if (!exists && shouldExist) {
|
||||
|
||||
@@ -18,11 +18,11 @@ actions.toggleGroupBy = 'toggleGroupBy'
|
||||
|
||||
export const useGroupBy = hooks => {
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => [
|
||||
hooks.flatColumnsDeps.push((deps, instance) => [
|
||||
...deps,
|
||||
instance.state.groupBy,
|
||||
])
|
||||
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
|
||||
hooks.flatColumns.push(flatColumns)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ function reducer(state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
function columnsBeforeHeaderGroups(flatColumns, { state: { groupBy } }) {
|
||||
function flatColumns(flatColumns, { state: { groupBy } }) {
|
||||
// Sort grouped columns to the start of the column list
|
||||
// before the headers are built
|
||||
|
||||
|
||||
+3
-2
@@ -133,7 +133,7 @@ export function useMountedLayoutEffect(fn, deps) {
|
||||
}, deps)
|
||||
}
|
||||
|
||||
export default function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
export function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
const debounceRef = React.useRef({})
|
||||
debounceRef.current.defaultFn = defaultFn
|
||||
debounceRef.current.defaultWait = defaultWait
|
||||
@@ -144,8 +144,9 @@ export default function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
wait = debounceRef.current.defaultWait
|
||||
) => {
|
||||
if (!debounceRef.current.promise) {
|
||||
debounceRef.current.promise = new Promise(resolve => {
|
||||
debounceRef.current.promise = new Promise((resolve, reject) => {
|
||||
debounceRef.current.resolve = resolve
|
||||
debounceRef.current.reject = reject
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user