0

I implemented a switch button on a single webpage to enable the user to select between two languages (english and french) - I am trying to use React and i18next library. So far the switch button does the job but I would like to save the user preference in local storage and until now I did not succeed to complete that task.

As you will notice in the code below I did some tests, replacing the initial state of the switch button (checked: false) by : checked: (lngSelect ? lngSelect : false)

But this doesn't work unfortunately. Also I have no idea if my code is clean enough, I mean if this is the usual way to do that kind of thing.

import React, { useState } from 'react';
import Switch from '@material-ui/core/Switch';
import { useTranslation } from 'react-i18next';
import footerStyles from '../../styles/footer.module.scss';

function SwitchBtn() {

    const lngSelect = localStorage.getItem('LngSelect');

    const { i18n } = useTranslation();
    const [state, setState] = useState({
        checked: (lngSelect ? lngSelect : false)
        // checked: false
    });

    function handleTranslation(state) {
        if (state) {
            i18n.changeLanguage('fr');
        } else {
            i18n.changeLanguage('en');
        }
        localStorage.setItem('LngSelect', JSON.stringify(state));
    }

    return (
        <Switch
            className={footerStyles.switchBtn}
            checked={state.checked}
            onChange={(e) => {
                setState({ checked: e.target.checked });
                handleTranslation(e.target.checked);
            }}
            name="languagesSwitch"
        />
    )
}

export default SwitchBtn
wentjun
  • 40,384
  • 10
  • 95
  • 107
chalatum
  • 67
  • 1
  • 3
  • 9

1 Answers1

2

It seems like you are storing the entire stringified state object into your local storage. In that case, you will need to use JSON.parse() to parse the JSON string into a valid JavaScript object, before assigning the initial value on your useState hook.

const lngSelect = JSON.parse(localStorage.getItem('LngSelect'));
const [state, setState] = useState({
  checked: lngSelect.checked,
});
wentjun
  • 40,384
  • 10
  • 95
  • 107
  • Thank you for your answer, I forgot about JSON.parse() indeed. I gave it a try, it solved some problems but now I've got some issues with the state of the switch component. In the console log I got this : "A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component." If you have some tips about how to solve this I would be glad to read them. – chalatum Jun 23 '20 at 16:29
  • @chalatum I think that is a slightly different question on its own, but you may refer to the explanation on this post: https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro – wentjun Jun 23 '20 at 16:34