I am using the Switch
component from MUI
library. I want to achieve where only one Switch
can be checked
at a time. For instance, if Switch A
is checked, when Switch B
is checked, Switch A
will be unchecked and vice versa. I am using the reducer pattern to achieve this.
Here is my code:
My reducer file:
// reducer.js
actionTypes = {
toggle_price: 'toggle_price'
}
export const initialState = {
fastprice: false,
spotprice: true,
}
export const toggleReducer = (state, action) => {
switch (action.type) {
case actionTypes.toggle_price: {
return {
...state,
[action.event.target.name]: action.event.target.checked
}
}
}
}
export const useToggler = ({ reducer = toggleReducer } = {}) => {
const [{ fastprice, spotprice}, dispatch] = useReducer(reducer, initialState)
const togglePrice = (event) => dispatch({ type: 'toggle_price', event })
return { togglePrice, fastprice, spotprice }
}
My component
//Component.js
const { togglePrice, spotprice, fastprice } = useToggler()
<FormControlLabel
control={<Switch onChange={e => toggleButton(e)} checked={fastprice} name='fastprice' />}label='Switch A' />
<FormControlLabel
control={<Switch onChange={e => toggleButton(e)} checked={spotprice} name='spotprice' />}label='Switch B' />
This code checks both Switch
components.
CodePudding user response:
you can hold the two radio buttons (or more) as a group to control the state of them.
for example combine the two radio button into one object and let just on radio button to be different.
try this solution.
const { togglePrice, radioGroup } = useToggler();
return (
<div className="App">
<FormControlLabel
control={
<Switch
onChange={(e) => togglePrice(e)}
checked={radioGroup.fastprice}
name="fastprice"
/>
}
label="Switch A"
/>
<FormControlLabel
control={
<Switch
onChange={(e) => togglePrice(e)}
checked={radioGroup.spotprice}
name="spotprice"
/>
}
label="Switch B"
/>
</div>
);
}
const actionTypes = {
toggle_price: "toggle_price"
};
export const initialState = {
radioGroup: {
fastprice: false,
spotprice: true
}
};
export const toggleReducer = (state, action) => {
switch (action.type) {
case actionTypes.toggle_price: {
const m = { ...state.radioGroup };
for (let key in m) {
m[key] = !action.event.target.checked;
}
return {
...state,
radioGroup: {
...m,
[action.event.target.name]: action.event.target.checked
}
};
}
default:
return state;
}
};
export const useToggler = ({ reducer = toggleReducer } = {}) => {
const [{ radioGroup }, dispatch] = useReducer(reducer, initialState);
const togglePrice = (event) => dispatch({ type: "toggle_price", event });
return { togglePrice, radioGroup };
};
live - DEMO
https://codesandbox.io/embed/elastic-star-8o6e6i?fontsize=14&hidenavigation=1&theme=dark