Skip to content

Commit

Permalink
fix(useTable): work around React 18 useReducer eager bailout change
Browse files Browse the repository at this point in the history
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
  • Loading branch information
henryqdineen committed Jul 22, 2022
1 parent b77ed82 commit a85d34e
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/hooks/useTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,15 @@ export const useTable = (props, ...plugins) => {
)

// Start the reducer
const [reducerState, dispatch] = React.useReducer(reducer, undefined, () =>
reducer(initialState, { type: actions.init })
const [reducerState, setReducerState] = React.useState(() =>
reducer(initialState, {
type: actions.init,
})
)

const dispatch = React.useCallback(
action => setReducerState(prev => reducer(prev, action)),
[reducer]
)

// Allow the user to control the final state with hooks
Expand Down

0 comments on commit a85d34e

Please sign in to comment.