Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use useSelector in the "restricted" function of a Block #6264

Closed
wesleybl opened this issue Aug 21, 2024 · 2 comments · Fixed by #6271
Closed

Cannot use useSelector in the "restricted" function of a Block #6264

wesleybl opened this issue Aug 21, 2024 · 2 comments · Fixed by #6271

Comments

@wesleybl
Copy link
Member

Describe the bug
I'm trying to make only a user with a Manager role add a certain block. I tried to restrict the block with the restricted function:

https://6.docs.plone.org/volto/development/how-to-restrict-blocks.html

To get the user I used the userSelector inside the restricted function. So when I click on a Text block when editing content, I get the error:

Uncaught TypeError: Cannot read properties of undefined (reading 'length')
    at areHookInputsEqual (react-dom.development.js:16249:1)
    at updateEffectImpl (react-dom.development.js:17078:1)
    at updateEffect (react-dom.development.js:17098:1)
    at Object.useEffect (react-dom.development.js:17862:1)
    at Object.useEffect (react.development.js:1634:1)
    at useIsMounted (SlashMenu.jsx:24:1)
    at PersistentSlashMenu (SlashMenu.jsx:161:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at updateFunctionComponent (react-dom.development.js:19588:1)
    at beginWork (react-dom.development.js:21601:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)
    at renderRootSync (react-dom.development.js:26434:1)
    at performSyncWorkOnRoot (react-dom.development.js:26085:1)
    at flushSyncCallbacks (react-dom.development.js:12042:1)
    at react-dom.development.js:25651:1

Analyzing the error, I found that it occurs because the useSelector call occurs inside a useMemo, which is not recommended. The useMemo in question is this one:

const availableBlocks = React.useMemo(

And the call to the restricted function, which calls useSelector occurs here:

? !item.restricted({ properties, block: item })

I believe it is not a good idea to remove useMemo. So what can be done? Is there any other way to restrict adding a block only to Manager?

This is related to #5137

To Reproduce
Steps to reproduce the behavior:

  1. To make reproduction easier, we will do it in a block of Volto itself.
  2. In the file:

https://github.com/plone/volto/blob/main/packages/volto/src/config/Blocks.jsx

import useSelector:

import { useSelector } from 'react-redux';
  1. Replace the restricted in the HTML block:

restricted: false,

to:

    restricted: () => {
      useSelector((state) => state.users?.user);
    },
  1. Add a Document and click on an empty Text block.

Expected behavior
There should be no error when clicking on a Text block.

Software (please complete the following information):

Volto 18.0.0-alpha.42
Plone 6.0.11
plone.restapi 9.7.0
CMF 3.5
Zope 5.9
Python 3.11.9 (main, May 14 2024, 08:32:26) [GCC 10.2.1 20210110]
PIL 9.5.0 (Pillow)

@wesleybl
Copy link
Member Author

The option I see would be to get the user in the PersistentSlashMenu component itself, and pass it to the restricted function. Would that be acceptable?

@davisagli
Copy link
Member

The option I see would be to get the user in the PersistentSlashMenu component itself, and pass it to the restricted function. Would that be acceptable?

@wesleybl That sounds like a pretty good solution to me. It's backwards compatible with existing implementations of restricted and sounds generally useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants