question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Reducer in useRowSelect relies on external state

See original GitHub issue

Pulled out of #2120, because this should be fixed even if 2120 is solved in another way or ends up being unrelated.

Describe the bug

The handler of toggleRowSelected action type reads isSelected from row objects:

As a result, when multiple selection changes happen within the same reducer run, toggleRowSelected uses the initial row selection state, regardless of whether another action updated it earlier in the same run.

Provide an example via Codesandbox!

Sorry I did not make one. The idea is just to do this:

assert(someRow.isSelected); // the bug shows only if row is selected

toggleAllRowsSelected(false) ;
someRow.toggleRowSelected(true);

What happens then is this:

  • The reducer handles toggleAllRowsSelected.
    • It clears selectedRowIds.
    • At this point, the isSelected property of rows has not been updated.
  • The reducer handles toggleRowSelected.
  • At last, react recomputes selectedFlatRows, which updates isSelected as a side effect (see #2170).

It is hard to make a minimal example, because this triggers observable bugs depending on when exactly React chooses to recompute selectedFlatRows, which is further obfuscated by #2170.

Expected behavior

Reducers should never access any information outside of previousState. Otherwise they no longer are predictable.

Replacing row.isSelected by id in state.selectedRowIds or something similar should work I believe.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:12
  • Comments:5

github_iconTop GitHub Comments

5reactions
codecadwalladercommented, Sep 14, 2020

+1 to add some noise. I spent a couple hours integrating/debugging inconsistency bugs before finding this issue and tossing out the code to roll our own implementation. The design/spec looks great so I’m hopeful it’s more stable in v8 🤞

4reactions
spectrascommented, Aug 9, 2020

@fparga a workaround is to

  • avoid useRowSelect, or
  • use it in controlled state mode (so, avoiding selection state update logic), or
  • use selectedRowIds directly, ignoring helper methods and isSelected attribute. It is an annoyance, but at least you can use all other parts of react-table normally.

Looking forward to v8 though 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reducer in useRowSelect relies on external state · Issue #2171
Provide an example via Codesandbox! Sorry I did not make one. The idea is just to do this: assert(someRow.isSelected); // the bug shows...
Read more >
Extracting State Logic into a Reducer - React Docs
Because the reducer function takes state ( tasks ) as an argument, you can declare it outside of your component. This decreases the...
Read more >
The State Reducer Pattern with React Hooks - Kent C. Dodds
A pattern for you to use in custom hooks to enhance the power and flexibility of your hooks.
Read more >
react-table - npm
React Table relies on memoization to determine when state and side effects should update or be calculated. This means that every option you ......
Read more >
How to use React useReducer hook like a pro - Devtrium
One good use case for useReducer is when you have multiple pieces of state that rely on each other. It's quite common when...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found