I'm new to react-native and I'm trying to create an application where it requires me to enable or disable buttons based on the press of a button. I'm trying using UseState But I'm confused as to how I can use multiple useState. For Example
Initial State:
Button A - Enabled
Button B - Disabled
Button C - Disabled
Button D - Disabled
On Press Button A
Button A - Disabled
Button B - Enabled
Button C - Enabled
Button D - Enabled
On Press Button C
Button A - Disabled
Button B - Disabled
Button C - Disabled
Button D - Enabled and so on. Can anyone help me to how I can use Mulitple use state in React Native
You can hold them in different states, like this:
const [buttonAEnabled, setButtonAEnabled] = useState(true);
const [buttonBEnabled, setButtonBEnabled] = useState(false);
const [buttonCEnabled, setButtonCEnabled] = useState(false);
const [buttonDEnabled, setButtonDEnabled] = useState(false);
This way, they are initialized like the way you wanted, button A is enabled and rest of the buttons are disabled.
I will assume that you will be using TouchableOpacity for the buttons, using disabled prop, you can bind the buttons with your state.
<View style={styles.container}>
{/* Button A */}
<TouchableOpacity
disabled={!buttonAEnabled}
onPress={handleButtonAPressed}
style={styles.button}
>
<Text>Button A</Text>
</TouchableOpacity>
{/* Button B */}
<TouchableOpacity
disabled={!buttonBEnabled}
onPress={handleButtonBPressed}
style={styles.button}
>
<Text>Button B</Text>
</TouchableOpacity>
{/* Button C */}
<TouchableOpacity
disabled={!buttonCEnabled}
onPress={handleButtonCPressed}
style={styles.button}
>
<Text>Button C</Text>
</TouchableOpacity>
{/* Button D */}
<TouchableOpacity
disabled={!buttonDEnabled}
onPress={handleButtonDPressed}
style={styles.button}
>
<Text>Button D</Text>
</TouchableOpacity>
</View>
Lastly, you should handle button presses.
const handleButtonAPressed = () => {
setButtonAEnabled(false);
setButtonBEnabled(true);
setButtonCEnabled(true);
setButtonDEnabled(true);
};
const handleButtonBPressed = () => {
// Whatever you want to do when button B is pressed
};
const handleButtonCPressed = () => {
setButtonAEnabled(false);
setButtonBEnabled(false);
setButtonCEnabled(false);
setButtonDEnabled(true);
};
const handleButtonDPressed = () => {
// Whatever you want to do when button D is pressed
};
You can also hold the button states as a single object like below:
const [buttonsActivityStatus, setButtonsActivityStatus] = useState({
buttonA: true,
buttonB: false,
buttonC: false,
buttonD: false,
});
Then you would have to change the state in a different way. Something like this:
setButtonsActivityStatus({
buttonA: false,
buttonB: true,
buttonC: true,
buttonD: true,
});
With this single object way, you can also use destructuring to make changing state shorter if you don't want to change every single state. For example, the code below will only change the state of buttonB to true, and keep the rest of the buttons the same.
setButtonsActivityStatus((oldStatus) => ({
...oldStatus,
buttonB: true,
}));
You can also check out this demo of this whole thing.
Related
Im trying to create 2 dropdown menus where depending on which are clicked would reduce a third view's flex number to accommodate the other 2 expanded views. Im using two useState variables to keep track of the 2 different dropdown menus, and calculate the flex as shown:
const [isFirstExpanded, setIsFirstExpanded] = useState(false)
const [isSecondExpanded, setIsSecondExpanded] = useState(false)
const calculateFlex = () => {
if (isFirstExpanded && isSecondExpanded) {
return 0; // This means both dropdowns are expanded, and should hide the third view
} else if (isFirstExpanded || isSecondExpanded) {
return 2; // Only one of the dropdowns are open, so half the size of the third view
} else {
return 4; // None of the dropdowns are open, so show the full view
}
}
<View style={{flex: 1}}>
<View style={{flex: calculateFlex, backgroundColor: "red"}}/> // View to be grown or shrunk depending on below views
<TouchableOpacity style={{flex: 1}} onPress={setIsFirstExpanded(!isFirstExpanded)}/>
<View style={isFirstExpanded ? styles.expandView : styles.hideView}/> // The dropdown that is hidden by default
<TouchableOpacity style={{flex: 1}} onPress={setIsSecondExpanded(!isSecondExpanded)}/>
<View style={isSecondExpanded ? styles.expandView : styles.hideView}/> // The dropdown that is hidden by default
</View>
This code leaves out some innocuous things, if needed I can copy/paste them. My problem occurs when the first view to be grown or shrunk doesn't seem to follow the calculate flex function. Not sure why, or if there is a better way to calculate this.
Hello guys I just started learning React-Native and I have a question about state.
I was practicing this concept trying to make a button that shows how many times I've pressed it.
My plan was to make a variable called clicks which will increase by 1 each time I press it and set the clickState to clicks. This is my code.
export default function App() {
const [clickState, setClicks] = useState(0)
let clicks = 0
return (
<View style = {styles.container}>
<StatusBar style="auto" />
<TouchableOpacity style={styles.button} onPress={()=>{setClicks(++clicks); console.log(clicks)}}>
<Text>Clicks : {clickState}</Text>
</TouchableOpacity>
</View>
);
}
this is the console
But apparently something is wrong and my clicks value goes random between 1 and 2 each time I click it instead of increasing by 1.
So I was curious about what I was doing wrong and why the values don't increase as I expected. I would also be glad if you showed how you would implement it if there is a better way.
Thanks guys.
You only need to update clickState, no need of variable clicks.
Also it won't rerender if we increment state value directly, so we should increment state by taking its previous state value like shown below
export default function App() {
const [clickState, setClicks] = useState(0)
return (
<View style = {styles.container}>
<StatusBar style="auto" />
<TouchableOpacity style={styles.button} onPress={()=>setClicks(prevState => prevState + 1)}>
<Text>Clicks : {clickState}</Text>
</TouchableOpacity>
</View>
);
}
<TextInput
// ...
returnKeyType = {"next"}
returnKeyType='go'
/>
this code is not leading the 'go'/'next' to next input field
How to Add "next" and "previous" arrows to the keyboard in iOS. And Set the "return"/"next" button on the keyboard to take the user to the next field in react native.
You can focus next input using reference of text input.
const refPasswordInput = useRef(null);
const focusOnPassword = () => {
if (refPasswordInput && refPasswordInput.current) {
refPasswordInput.current.focus();
}
};
const hideKeyboard = () => {
Keyboard.dismiss()
};
<TextInput
...
blurOnSubmit={false}
returnKeyType="next"
onSubmitEditing={focusOnPassword}
/>
<TextInput
ref={refPasswordInput}
...
returnKeyType="done"
onSubmitEditing={hideKeyboard}
/>
function App() {
const [state, setTextState] = useState("Press the button!");
// this is the variable I want to output incremented by 1
// each time the button has been pressed
let i = 0;
return (
<View>
<Text>{state}</Text>
<Button
onPress={() => setTextState(`The button has been pressed ${++i} time(s)`)}
title={"Button 1"}
/>
</View>
);
}
The outputs sequence is something like this:
initial - The button has been pressed 0 time(s)
1 - The button has been pressed 1 time(s)
2 - The button has been pressed 2 time(s)
3 - The button has been pressed 1 time(s)
4 - The button has been pressed 2 time(s)
If the function really cannot contain variable outside of his "state", how come the {i} variable still is reachable and incremented (twice-only, but still incremented).
You can't use i as you did (as explained in this comment). You might want to look into the useRef hook for future reference as it's a good way to have persist variable throughout the lifetime of your component.
However, based on the example you provided, I'd highly recommend that you just use the state:
function App() {
const [buttonCount, setButtonCount] = useState(0);
return (
<View>
<Text>The button has been pressed {buttonCount} time(s)</Text>
<Button
onPress={() => setButtonCount(prevButtonCount => prevButtonCount + 1)}
title={"Button 1"}
/>
</View>
);
}
onPress doesn't show me the id of my touchable opacity component when I press on it. He just shows me undefined.
render() {
var rows = [];
var i = 0;
while(i<5){
rows.push(<TouchableOpacity id={i} activeOpacity={0.9} onPress={() => alert(this.props.id)}>
<View>
</View>
</TouchableOpacity>);
i++;
}
return {rows}
}
I want to when I press on it, it shows the id of touchable opacity. Please help me
The component you have for this render() function would need to have a prop id for this to show an alert, but I think you are wanting to show each value of i. Due to i never going out of scope within this function (as it is var), if you attempted to just do alert(i) it would show 5 for each button, but if you use const inside the while to store the current value of i, each button will have the correct value:
while (i < 5) {
const temp = i;
rows.push(
<TouchableOpacity
id={i}
activeOpacity={0.9}
onPress={() => alert(temp)}
>
<View />
</TouchableOpacity>,
);
i++;
}
You can't use a prop you are assigning in another prop you are assigning like you were trying to do.