How to control two elements separately for toggling states to true
and false
.Is there a way to simplify this code? Writing different states and functions for every component seems to be the wrong approach. And what if there would be more than two components?
const [active, setActiveItem] = React.useState(false);
const [active2, setActiveItem2] = React.useState(false);
function toggle() {
setActive((active) => !active);
}
function toggle2() {
setActiveItem2((active) => !active);
}
return (
<View style={styles.row}>
<CustomButton onPress={toggle} active={active} />
<CustomButton onPress={toggle2} active={active2} />
</View>
);
}
CodePudding user response:
Perhaps so:
const [actives, setActives] = React.useState({
active1: false,
active2: false,
active3: false,
active4: false,
});
const toggle = (key) => setActives((actives) => ({ ...actives, [key]: !actives[key] }));
return (
<View style={styles.row}>
<CustomButton onPress={() => toggle('active1')} active={actives.active1} />
<CustomButton onPress={() => toggle('active2')} active={actives.active2} />
<CustomButton onPress={() => toggle('active3')} active={actives.active3} />
<CustomButton onPress={() => toggle('active4')} active={actives.active4} />
</View>
);
CodePudding user response:
I think I would do something like this
const [active, setActiveItem] = React.useState(false);
const [active2, setActiveItem2] = React.useState(false);
function toggle(setFunction) {
setFunction((someState) => !someState);
}
return (
<View style={styles.row}>
<CustomButton onPress={()=>toggle(setActiveItem)} active={active} />
<CustomButton onPress={()=>toggle(setActiveItem2)} active={active2} />
</View>
);
}
CodePudding user response:
You can use hash map for keeping state, instead of boolean
const [state, setState] = useState({
0: false,
1: true,
2: false
});
return (
Object.keys(state).map((id) => <CustomButton
key={id}
onPress={() => {setState(prev => ({...prev, [id]: !prev[id]}))}}
active={state[id]}
/>
)
CodePudding user response:
Create a useToggle
custom hook and use it twice:
const { useState, useCallback } = React;
const useToggle = (initial = false) => {
const [active, setActive] = useState(initial);
const toggle = useCallback(() => {
setActive(prev => !prev);
}, []);
return [active, toggle];
}
const Demo = () => {
const [active1, toggle1] = useToggle();
const [active2, toggle2] = useToggle(true);
return (
<div>
<button onClick={toggle1}>Toggle 1 - {active1 ? 'on' : 'off'}</button>
<button onClick={toggle2}>Toggle 2 - {active2 ? 'on' : 'off'}</button>
</div>
);
}
ReactDOM
.createRoot(root)
.render(<Demo />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
CodePudding user response: