Home  >  Q&A  >  body text

The display and value cannot be updated when the MUI switch is clicked.

<p>I'm having trouble with the Material UI toggle switch I'm using in my current project. When the component loads, if I log the value in the console, the initial value is correct. However, if I click the switch from "Yes" to "No", the switch correctly renders showing "No" is selected and the console logging fires again, but the value still shows "Yes". If I click the switch again and try to toggle it back to "No", the toggle just re-renders without flipping, the console logging fires again and the value is now updated to "No".So basically the first click flips the switch and the second click flips the value. I've used the same toggle switch before with no issues, so can anyone tell me what I need to fix to get the switch and value to flip when clicked? </p> <p><strong>Handling input changes:</strong></p> <pre class="brush:php;toolbar:false;">const handleInputChange = e => { const { name, value } = e.target; setValues({ ...values, [name]: ( typeof value === 'string' ? (value).replace(/ (?= )/g, '').trimStart() : value ) // If the value is a string, remove leading spaces and multiple spaces }); };</pre> <p><strong>Switch called from form: </strong></p> <pre class="brush:php;toolbar:false;"><ToggleSwitch onChange={handleInputChange} label1='No' label2='Yes' name='useForCalcs' value={values.useForCalcs} /></pre> <p><strong>ToggleSwitch component:</strong></p> <pre class="brush:php;toolbar:false;">import * as React from 'react'; import {Box, Switch, Typography} from '@material-ui/core'; export default function ToggleSwitch(props) { const { label1, label2, name, onChange, value} = props; const [checked, setChecked] = React.useState(false); const convertToEventParams = (name, value) => ({ target: { name, value } }); const curValue = value === 1 ? true : false; const handleSwitch = e => { setChecked(e.target.checked); }; React.useEffect(() => { setChecked(curValue); }, [curValue]); // Re-render the toggle switch every time the checked value changes const handleChecked = e => { handleSwitch(e); onChange(convertToEventParams(name, (checked === false ? 1 : 0))); // Convert True/False to 1/0 value }; return ( <Box> <Typography> {label1} {<Switch name={name} checked={checked} value={checked} onChange={handleChecked} inputProps={{'aria-label': 'switch'}} />} {label2} </Typography> </Box> ); }</pre> <p><br /></p>
P粉638343995P粉638343995453 days ago503

reply all(1)I'll reply

  • P粉298305266

    P粉2983052662023-08-16 10:48:25

    You are handling the state and selected value in the ToggleSwitch component. You have both local state (checked) and a prop (value) and you want to synchronize them.

    To resolve this issue, make sure the switches and values ​​are properly synchronized

    You are passing a value prop from the parent component and you can use that prop directly to determine the state of the switch. You can simplify component code by removing unnecessary states and effects.

    You can directly use the value prop to determine the initial state of the switch, and use the onChange function to update the parent component.

    import React from 'react';
    import { Box, Switch, Typography } from '@material-ui/core';
    
    export default function ToggleSwitch(props) {
      const { label1, label2, name, onChange, value } = props;
    
      const handleChecked = () => {
        const newValue = value === 0 ? 1 : 0; // 切换值
        onChange({ target: { name, value: newValue } });
      };
    
      return (
        <Box>
          <Typography>
            {label1}
            <Switch
              name={name}
              checked={value === 1}
              onChange={handleChecked}
              inputProps={{ 'aria-label': 'switch' }}
            />
            {label2}
          </Typography>
        </Box>
      );
    }

    reply
    0
  • Cancelreply