The display and value cannot be updated when the MUI switch is clicked.
P粉638343995
2023-08-15 20:20:45
<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>
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.