How to determine mouse events in React Native (mobile)? - react-native

I need to use a callback function for the mouse click event. Below code is working in React web app:
const checkAnswer = (e: React.MouseEvent<HTMLButtonElement>) => {
const answer = e.currentTarget.value // here .value property is undefined and gives error in React-Native. Just e.currentTarget is defined.
const correct = questions[number].correct_answer === answer
if(correct) setScore(prev => prev + 1)
}
But I couldn't apply it on React Native (mobile) for Pressable or TouchableOpacity.
This is the render part of React web app's code:
<button value={answer} onClick{checkAnswer} />
and I try to apply it on React Native. The value will be passed to button's value. But there is no "value" option in native's Pressable component. Therefore I am confused
Any help?

you can determine touch events by following
<View onTouchStart={(e) => {console.log('touchMove',e.nativeEvent)}} />

Here is some similar scenario what I could able to understand from the question.
There is a Score state which will store the user's score of a quiz game.
There is a array of question where all the options and correct option are given.
There will be a button for the option, if user choose a option, and based on that it will validate if user is correct or not.
It might not be the exact scenario of you. But this could definitely help to solve your scenario.
Here is a solution for the scenario => solution.
If you click on the solution link you will be redirect to a page which is similar to the screenshot attached below. On very right you will find "My Device", "Android", "ios", choose any and run. Run via "my device" with expo app installed in your mobile if you don't want to be in queue for some certain time.
Note: from your code this is for React web:
<button value={answer} onClick{checkAnswer} />
but in React Native you have to use a click event like this:
<TouchableOpacity onPress={()=>buttonHandler()}></TouchableOpacity>
Here ()=> and () extra need to be added to work a function properly.
Also instead of .map() function you can use FlatList to improve your app. FlatList support lazy loading.

Related

How to add a screen switcher component in react native

Being a newbie to the field of app development, I actually don't know the name of this UI component .
This component basically act as a switcher between two screen, which shows up Explore screen when Explore is clicked and My Community screen when My Community is clicked
Someone please help me to know what to call this component and which npm package need to be used to deploy it.
THANKS IN ADVANCE!!!
You can use the switch component and its boolean value to conditionally display different screens/components.
Basic example using setState:
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
return (
<View>
<Switch
onValueChange={toggleSwitch}
value={isEnabled}
/>
{isEnabled ? <Text>Placerholder Screen 1</Text> : <Text>Placerholder Screen 2</Text>}
</View>
);
But in this situation I would advise you to use Tabs instead of a Switch. React Navigation is a great library to help you with this. You may want to look at the bottom tabs, material bottom tabs or material top tabs.

How to pass params in React Native Navigation for the goBack() function

I know this is a stupid question.
I have a component lets call it Component that is used in several screens for Example Screen1,Screen2,...
And in the Component I am navigating to a new Screen when the user click a button, lets call it ImagePicker.
my Question is how do I go back and pass a parameter( in this case image data) and get it back in the Component
I tried using navigation.goBack({img: image}) but that didn't work. I also can't use navigation.navigate('Screen') since my functions are in the Component component.
So what is the best solution for my problem ?
We cannot pass any params to the goBack method.
If we have to do so then, we can use the navigate method to navigate to the back screen, and using this method we can pass the params to the previous screen.
For ex.
navigation.navigate('PrevScreenName', {key: value})
Check out the official docs for the react-navigation.
React Navigation
If I understand your problem well, just do
navigation.navigate('Screen', {img: image})
instead of navigation.goBack({img: image}) and it should work
In the component code, I would pass along a callback function to the image picker screen
handleImageData = (data) =>
{
// do whatever
}
...
navigation.navigate('ImagePickerScreen',{mycallback:this.handleImageData});
and then in the screen code just call it like
this.props.route.params.mycallback(data);
navigation.goBack();

React Native and React Native Navigation - Handle Back (goBack) issue

thank you for taking time to read & answer this question. I'll give my best to explain the issue I'm having.
The HomeStack component holds bottom navigation for four screens. One screen that is giving me a headache is ProjectsStack
export const ProjectsStack = (): ReactElement => {
return (
<ProjectsStackNav.Navigator initialRouteName='ProjectsScreen' screenOptions={defaultScreenOptions}>
<ProjectsStackNav.Screen name='ProjectsScreen' component={ProjectsScreen} />
<ProjectsStackNav.Screen name='CompletedProjectsScreen' component={CompletedProjectsScreen} />
<ProjectsStackNav.Screen name='ProjectTasksScreen' component={ProjectTasksScreen} />
<ProjectsStackNav.Screen name='CompletedProjectsTasksScreen' component={ProjectTasksScreen} />
</ProjectsStackNav.Navigator>
);
};
As you can see the ProjectTasksScreen is a component that renders a project based on the props => if it's open it will render ProjectTasksScreen otherwise it will render CompletedProjectsTasksScreen which is basically the same screen (reusability at its finest lol)
In order to go to the CompletedProjectsTasksScreen, you need to come from ProjectTasksScreen.
Now, the issue is when you want to go back from CompletedProjectsTasksScreen it will not go to ProjectTasksScreen, rather it will navigate to the previous screen of ProjectTasksScreen which is ProjectsScreen.
Is there a better solution to this problem than refactoring everything into it's screen & component?
navigation.push method instead of navigation.navigate may resolve your issue
https://reactnavigation.org/docs/navigating/#navigate-to-a-route-multiple-times

loop and get all TextInput value in a component/screen

I know that the practice of react native is to use onChangeText for change value as follow.
<TextInput
onChangeText = {(text)=> this.setState({myText: text})}
value = {this.state.myText}
/>
However, I wonder if i could do something like this. To summarise, I want to loop through all the TextInput and get the ref and value. I just want to do things in javascript way as follow. Is that possible to be done?
<TextInput id="id1" ref={ref => (this.remark = ref)} />
<TextInput id="id2" ref={ref => (this.remark1 = ref)} />
onSubmit = () => {
forEach(TextInput in component) {
console.log(TextInput.id) <- note id is custom property
console.log(TextInput.refName)
console.log(TextInput.value)
}
}
Yes, but I wouldn't recommend this approach. You could simply create an array of refs and loop through it in your onSubmit function.
forEach(TextInput in component) {
This is not possible in any javascript environment (not only because forEach and for..in syntax is different but also you can't expect to be able to loop over component elements by type (?) and get them)
What you want to do is not javascript way but old style browser way:
there are no ids in react-native
technically you could get uncontrolled TextInput's value like you would do in plain react in browser environment (via this.textInputRef._lastNativeText) but it's discouraged in react-native, most likely because because instead of DOM react native has to render to native views which all differ depending on the platform (iOS, Android, Windows, etc) but have to work the same
So it's not only impossible in react native but in plain react as well. It looks to me like you want to create a form, and sooner or later you will find out that you want validation or transformation on your inputs and switch back to controlled components anyway

react native route flux re-render component on stack pop

How do you re-run React Component Lifecycle methods to determine if a re-render is necessary when transitioning back to previous screens from stack using React Native Router Flux?
Scenario: Scene A -> B -> A
Lets say, A is the initial scene and we navigate from A to B with a push i.e Actions.SceneB. From B to A with a Pop. When the stack is popped to show Scene-A, none of the React Component methods are called for Scene-A. How do I determine if a re-render is necessary? I searched the Issues listed on the github repo and many seems to have this problem without a solution. How is this problem addressed?
I have the ugly work around of calling Actions.refresh() with a setTimeout.
Work Around that works!
This workaround seems to be hacky. There must be a better way to hook into component lifecycle to determine if a re-render is required. Perhaps a callback into the Component?
<TouchableHighlight underlayColor='#efefef' onPress={() => { Actions.pop(); setTimeout(()=> Actions.refresh(), 500)}} style={styles.cancel}>
Options that do not work
Actions.pop({type: 'reset'})
OR
Actions.refresh({"key" : "sceneA"})
Work Around that works! This workaround seems to be hacky. There must be a better way to hook into component lifecycle to determine if a re-render is required.
<TouchableHighlight underlayColor='#efefef' onPress={() => { Actions.pop(); setTimeout(()=> Actions.refresh(), 500)}} style={styles.cancel}>
This will call shouldComponentUpdate() method which gives an option to determine, if a re-render is required.
I was facing the same issue below code gave me required result.
let count = 0;
moveToMainScreen = () => {
count += 1;
Actions.pop({ refresh: { test: count } });
};
<Button onPress={this.moveToMainScreen}> Click </Button>