Skip to content

Commit 06703a5

Browse files
authored
fix(useTable): work around React 18 useReducer eager bailout change (#4207)
React 18 removed some logic from `useReducer()` where a dispatch would eagerly call reducers to recompute the state so now reducers will be called after render. This poses a problem for `useTable()` because during render it mutates the `instance` by spreading in `props` and does not expect this to happen before reducer execution. We were passing a `pageCount: undefined` prop to `useTable()` and by the time the reducer executes `instance.pageCount` is been overwritten, causing a bug in our app. In the Codesandbox reproduction you can see that hitting the "next" button will not work. I understand that our abstraction around `useTable()` probably shouldn't be passing this prop when `undefined` but the behavior change was unexpected and I wonder if it breaks any other assumptions that this library makes. The fix I made here is to just replace `useReducer` with `useState`, which still has the eager bailout check. React PR in question: facebook/react#22445 Codesandbox repro: https://codesandbox.io/s/cool-edison-45tkqx?file=/src/App.js:1331-1358
1 parent b77ed82 commit 06703a5

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

src/hooks/useTable.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,15 @@ export const useTable = (props, ...plugins) => {
129129
)
130130

131131
// Start the reducer
132-
const [reducerState, dispatch] = React.useReducer(reducer, undefined, () =>
133-
reducer(initialState, { type: actions.init })
132+
const [reducerState, setReducerState] = React.useState(() =>
133+
reducer(initialState, {
134+
type: actions.init,
135+
})
136+
)
137+
138+
const dispatch = React.useCallback(
139+
action => setReducerState(prev => reducer(prev, action)),
140+
[reducer]
134141
)
135142

136143
// Allow the user to control the final state with hooks

0 commit comments

Comments
 (0)