dataesr / react-dsfr

Non-official React components of the official french Système de Design de l'État.
https://dataesr.github.io/react-dsfr/
MIT License
44 stars 22 forks source link

RadioGroup isn't update with new value #325

Open sylvainlg opened 1 year ago

sylvainlg commented 1 year ago

Hi

I work on ConsentModal / ConsentService but i can't figure it out how to update all optional consents more than once. The first toggle works well but the following don't do anything (internalConsents is correctly updated). I think the issue may come from RadioGroup but i can't test

My code:

I have a function acceptDeclineAll which allows to modify the internal state (internalConsents) of all the optional consents.


I got an error on the second state change on a radio button :

Uncaught TypeError: a is not a function
    at index.min.cjs.js:1:1

  const { consents } = useConsentContext();
  const [internalConsents, setInternalConsents] = useState(consents);

  const acceptDeclineAll = (status: ConsentStatus) => {
    if (status === ConsentStatus.ACCEPT) {
      setInternalConsents(Object.entries(Consents).reduce((acc, [, v]) => ({ ...acc, [v]: true }), {}));
    } else {
      setInternalConsents({
        ...Object.entries(Consents).reduce((acc, [, v]) => ({ ...acc, [v]: false }), {}),
        [Consents.MANDATORY]: true
      });
    }
  };

  const onChange = (consent) => (status) => {
    setInternalConsents({ ...internalConsents, [consent]: status === 'accept' });
  };

<ConsentManager ... >
      <ConsentService
        acceptLabel="Tout accepter"
        defaultConsent={consents[Consents.ALL] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
        description=""
        name={Consents.ALL}
        refuseLabel="Tout refuser"
        title="Préférences pour tous les services."
        onChange={acceptDeclineAll}
        value={internalConsents[Consents.ALL] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
      />
      <ConsentService
        acceptLabel="Accepter"
        defaultConsent={ConsentStatus.ACCEPT}
        description="Ce site utilise des cookies nécessaires à son bon fonctionnement qui ne peuvent pas être désactivés."
        disabled
        name={Consents.MANDATORY}
        refuseLabel="Refuser"
        title="Cookies obligatoires"
      />
      <ConsentService
        acceptLabel="Accepter"
        defaultConsent={consents[Consents.FACEBOOK_PIXEL] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
        description="Identifie les visiteurs en provenance de publications Facebook."
        name={Consents.FACEBOOK_PIXEL}
        onChange={onChange('facebook_pixel')}
        refuseLabel="Refuser"
        title="Facebook Pixel"
        value={internalConsents[Consents.FACEBOOK_PIXEL] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
      />
      <ConsentService
        acceptLabel="Accepter"
        defaultConsent={consents[Consents.GOOGLE_ANALYTICS] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
        description="Permet d'analyser les statistiques de consultation de notre site."
        name={Consents.GOOGLE_ANALYTICS}
        onChange={onChange('google_analytics')}
        refuseLabel="Refuser"
        title="Google Analytics"
        value={internalConsents[Consents.GOOGLE_ANALYTICS] ? ConsentStatus.ACCEPT : ConsentStatus.REFUSE}
      />
</ConsentManager>
desoindx commented 1 year ago

Hello Sylvain,

I'll take a look.

sylvainlg commented 1 year ago

After some research, I think the error is fire in Modal component :

Error :

Uncaught TypeError: a is not a function
    at index.min.cjs.js:1:1

Cause, hide not defined :

  const handleAnimatedUnmount = () => {
    handleModal(false);
    setTimeout(() => {
      if (focusBackTo) focusBackTo.focus();
      hide();
    }, MODAL_ANIMATION_TIME);
  };

minified as :

z=()=>{_(!1),setTimeout((()=>{p&&p.focus(),a()}),300)}

The root cause can be in the ConsentModal component, the close function is not set.

In ConsentManager, the fix can be :

replace

        setIsOpen={openConsentModal}

by

        close={() => setIsModalOpen(false)}

but the bug still seems to be present in some cases, I don't understand what's going on

sylvainlg commented 1 year ago

Up @desoindx

sylvainlg commented 1 year ago

Hi @desoindx Do you think you will have some time to look into this problem? Thank you