Change value of a state with 3 different buttons (React Native) - react-native

How can I dynamically change the value of a state when I click on one of the 3 buttons that I have, for example, I have button 1 with the value: 'State1' and I have button 2 with the value: 'state2', how can I do it? that when clicking on button one, the state takes the value of button 1 and when clicking on button 2, that state is replaced with the value of button 2, is this possible? Any help would be amazing!

Yes. It's possible.
When you press the buttons, they invoke onPress function.
You can use setState function inside the onPress.

Going off your answer, it is only a matter of using the correct props (usually onPress for buttons) and updating your state's initial value.
enum ReadLevel {
Beginner = 'Beginner (1 to 6)',
Intermediate = 'Intermediate (6 to 9)'
}
export function YourComponent() {
const [readLevel, setReadLevel] = useState(ReadLevel.Beginner);
return (
<Fragment>
<TouchableWithoutFeedback onPress={() => setReadLevel(ReadLevel.Beginner)}>
<Text>
{ReadLevel.Beginner}
</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={() => setReadLevel(ReadLevel.Intermediate)}>
<Text>
{ReadLevel.Intermediate}
</Text>
</TouchableWithoutFeedback>
</Fragment>
);
}

Related

Touchable view and activating another components animation

New to react native and in a component, I have a list of views that include a checkbox (react-native-bouncy-checkbox). Each view is wrapped in a TouchableWithoutFeedback(So I can click the entire view, not just the checkbox) and I have a boolean useState to tell the checkbox whether to display the check or not.
The issue I'm at is that I chose the library for the checkbox because the animation when it's clicked looks very nice. However, the animation doesn't play if I hit the view ~ only if I hit the actual checkbox, which is rather small in my app.
Is there any way to tell another component that it needs to act like it was pressed, so it can play its animation?
Code for clarity:
const Task = ({ id, text }: Types) => {
const [checked, setChecked] = React.useState(false);
return (
<TouchableWithoutFeedback onPress={() => setChecked(!checked)}>
<View style={styles.container} >
<BouncyCheckbox
disableBuiltInState={true}
isChecked={checked}
fillColor="blue"
iconStyle={{ borderColor: 'gray' }}
/>
<Text>{text}</Text>
</View>
</TouchableWithoutFeedback>
)
};
Okay figured it out. Apparently React native allows you to create refs to other components and you can use the reference.onPress() to activate the animation.

How to show Modal to user before changing routes in React Navigation

So I'm wondering if I'm just not using the right vocabulary in my search - but what I thought might be cool for an app I'm working on would be:
A user starts editing their post.
In case they go back or press a tab to go to another page before
they press "Update".
The screen change is intercepted and a modal shows up and asks if
they want to keep their changes.
I know you can add event handlers - https://reactnavigation.org/docs/navigation-events/ but I'm not sure if these are what I need, I've tested and the prevent default didn't seem to do what I thought it would. That and I couldn't find a way to find what the next intended route that the app would need to go to once they have said "Dismiss" on the modal.
Could anyone point me in the right direction please?
you can create your own modal and back button so you can control what each item do
this.state={
modalConfirm: false
}
goBack = () => { //your goback function }
cancel = () => { this.setState ({modalConfirm :false})
<View>
<TouchableOpacity onPress={()=> this.setState({modalConfirm: true})>
<Icon name='arrow-left' />
</TouchableOpacity>
<Modal visible={this.state.modalConfirm}>
<Text>Do you want to go back? </Text>
<Button title='Go back' onPress={this.goBack} />
<Button title='No' onPress={this.cancel} />
</Modal>
<View>
//your content
</View>
</View>

How do I handle press and unpress touchable component with style changes?

The idea is to create a specific Touchable component acting like a button and have a feeling of pressed and unpressed, and using this component many times on my app but only one can be pressed at a time. If one is touched and then another one is touched, the first one should be unpressed and the second one should be pressed. The idea is not to use Redux to solve this problem.
I'm already handling which component was pressed, and sending through props the actions to the component. But i don't know how to manage all buttons at the same time in a generic way, by that I mean, not creating a variable to each button.
my App:
<View>
<ActivityButton activityTitle={"B1"} submit={() => this.submitHandler("B1")} />
<ActivityButton activityTitle={"B2"} submit={() => this.submitHandler("B2")} />
</View>
my Component (ActivityButton):
this.state={active:false}
<TouchableOpacity style={this.state.active ? styles.buttonPress : styles.button} onPress={this.props.submit}>
<View>
<Text>{this.props.activityTitle}</Text>
</View>
</TouchableOpacity>
I assume what you trying to do something like a Radio button groups? If your buttons only located in single page, you can achieve by using state in MyApp to check which buttons is enabled instead of button itself.
MyApp
constructor(props) {
super(props);
this.state = {
buttonIdThatEnable: "",
};
}
submitHandler = (buttonId) => {
this.setState({
buttonIdThatEnable: buttonId,
});
}
render() {
return (
<View>
<ActivityButton
activityTitle={"B1"}
active={this.state.buttonIdThatEnable === "B1"}
submit={() => this.submitHandler("B1")}
/>
<ActivityButton
activityTitle={"B2"}
active={this.state.buttonIdThatEnable === "B2"}
submit={() => this.submitHandler("B2")}
/>
</View>
)
}
ActivityButton (Use props.active to determine style)
<TouchableOpacity style={this.props.active ? styles.buttonPress : styles.button}
onPress={this.props.submit}>
<View>
<Text>{this.props.activityTitle}</Text>
</View>
</TouchableOpacity>
If your Buttons are located in different components and you do not want to use Redux, you may consider the React Context API

Button action called without pressing it

I had a render function with a button that redirects to another page.
When I enter the page, it does immediately trigger to the page (without cliking the button) and display the following warning message : cannot update during an existing state transition
render () {
return (
<View>
<Text > {this.state.text} </Text>
<Button onPress={this.props.navigation.navigate('Home')}
title = "Go Home" />
</View>
);
}
I solved it with the following code, but I don't understand why the previous did'nt work.
render () {
return (
<View>
<Text > {this.state.text} </Text>
<Button onPress={() => this.props.navigation.navigate('Home')}
title = "Go Home" />
</View>
);
}
Could you explain me why the behavior is different ?
When you do:
this.props.navigation.navigate('Home')
You are calling the navigate function and passing it's output to the onPress.
When you do:
() => {
this.props.navigation.navigate('Home')
}
you are passing an arrow function (not a call) and this function contains a call to your navigate, but the arrow function isn't called until the button is pressed.
Your solution with the use of an arrow function is the right thing to do, because you have to pass a parameter, if you didn't have to pass it you could do:
<Button onPress={this.someOfMyFunctions.bind(this)}
title = "Go Home" />
This would result in the someOfMyFunction call when the button is clicked.
That happens because you are actually calling the function in the first case.
In your second code block you are passing the function to the onClick handler which is what you want to do. The value should be a function, not a call to a function.
Hope that helps.

How can I set onPress event in a child component?

I have a file called SplashScreen.js with a StackNavigator. Sample code:
Inside my SplashScreen.js I have a component called "Login" and INSIDE Login I have a component called "TouchbleOpacity"
What I need is to change the "onPress" event of my TouchbleOpacity component. So I'll be able to navigate in my Navigator (that are inside my SplashScreen.js). The onPress event should look similar to this: onPress={() => navigation.navigate('TelaCadastrar01')
If there is a better way to change the onPress event of my TouchbleOpacity, please tell me, thanks!
I don't know if this is what you are looking for, but i'll give it a try:
In your Login Component you do:
//first button
<TouchableOpacity onPress={this.props.onPress} >
<Text> ... </Text>
</TouchableOpacity>
//second button
<TouchableOpacity onPress={this.props.onPressButton2} >
<Text> ... </Text>
</TouchableOpacity>
Now you are able to pass any onPress function to your Login Component. e.g.
<Login onPress={() => navigation.navigate('TelaCadastrar01')} onPressButton2={() => console.log('second scene')}/>