onClick button event error in react-native - react-native

Render Error
Here is my code:
function Adddetails () {
set(ref(db, 'users/' + phone), {
phone: phone,
parent: parent
}).then(() => {
alert('data updated');
})
.catch((error) => {
alert(error);
});
};
button design code is here

As the error displays, the components in react-native should always start with an uppercase.
in your case you are calling <button/> which is not a react-native component.
therefore, it should be switched to <Button />

Seems like you are confusing React concepts with React Native. In React Native we don't have HTML based button. Either use Button component imported from react-native or Use a TouchableOpacity from react-native.
Also if that button is your own component make sure it Starts with a Captial B <Button/>

Related

React Native Switch not animating when using React Navigation

I am trying to add a Switch to my App, and its animation is not working. I tried to create a Snack and noticed that it works without navigation (see this snack) but doesn't work when it is inside a Screen (see this snack).
It seems to be a problem just in Android.
The Switch code is just it:
const MySwitch = () => {
const [value, setValue] = React.useState(false);
return <Switch value={value} onValueChange={setValue} />;
};
Am I doing something wrong? Is it a problem with Expo, React Navigation or Switch?
In the worst case, how can I animate the component on my own?
Current behavior / Expected behavior:
React Navigation versions:
"#react-navigation/native": "^5.7.2",
"#react-navigation/bottom-tabs": "^5.7.2",
came upon this bug as well, exactly as described.
I implement a settings page where if you toggle one option, another toggle option is displayed. The second Toggle does not suffer from this bug, and this is 100% consistent. So my guess is that he bug is triggered only for Switch components that are rendered on the initial render pass somehow.
as a workaround for this bug, introducing a small delay of 10ms for rendering Switch completely resolves the issue without visible side effects.
function useDelay(ms: number) {
const [gate, setGate] = useState(false);
useEffect(() => {
setTimeout(() => {
setGate(true);
}, ms);
});
return gate;
}
const delayRender = useDelay(10);
return (
<>
{delayRender && (
<Switch />
)}
</>
);

Adding longpress event in react native

I have one input box, through which I am adding some text, on longpress I have to make the added fields as editable, how can I do that in react native.
If you want to make your filed clickable without seeing a buton then you should use touchableopacity.
Try this;
<TouchableOpacity onLongPress={this._onLongPress}>
<Input/>
</TouchableOpacity>
_onLongPress = () => {
this.setState({
makeEditableFunction: true
})
}

react native webview navigation issue

I am making a test with react navigaton and webview , I have 2 screens , Home and Details , at details screen I am calling / opening a webpage inside webview , let's say that I am calling stackoverflow.com (Page A) , my problem is that when user click a link of the stackoverflow page and navigate and after wants to go back to the previous page (Page A) , it doesn't go , its going or navigating to the Home screen !!!
how can I let The user go back to the previous page. ?
that 's how I am calling the page
<WebView
javaScriptEnabled
source={{uri: 'https://stackoverflow.com/'}}
style={{marginTop: 20}}
/>
As we know built in back button is not provided in iOs but it is provided in android .
So for considering both platform there is two possibility.
Android.
-> For android you have to define BackHandler so here are the step.
import it like this.
import {BackHandler } from 'react-native'.
initialize backhandler inside the life cycle methods.
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
handleBackPress = () => {
if (this.state.canGoBack) {
this.refWeb.goBack();
}
else{
this.props.navigation.goBack(null)
}
return true;
}
define a userdefine variable canGoBack inside the status.
constructor(props) {
super(props)
this.state = {
canGoBack: false
}
}
create a method which detect the change in navigation of the webview and bind it with the web view.
onNavigationStateChange(navState) {
this.setState({
canGoBack: navState.canGoBack
});
}
Bind it like this.
<WebView
ref={(myWeb) => this.refWeb = myWeb}
onNavigationStateChange={this.onNavigationStateChange.bind(this)}
source={{ uri: 'https://stackoverflow.com/questions/51712310/react-
native-webview-navigation-issue' }} />
And thsts it you are ready to go..
iOs
For iOs you didn't have to bother too much.
Create a button for back press above the webview or according to your design logic
Follow the above webview and navigation logic . forgot about the backhandler and set this code inside the onPress() method of your created button of backpress
if (this.state.canGoBack) {
this.refWeb.goBack();
}else{
this.props.navigation.goBack(null)
}
Note : Here I use stackNavigator for screen navigation so i used this.props.navigation.goBack(null) this code. if you didn't use it then dont consider this code and replace with your feasible navigator code in else condition
Thankyou..

setNativeProps on Button Component

When I define a button in React Native as:
<Button ref="buttonRef" title="Button" onPress={this.buttonPressed}/>
And its onPress function as:
buttonPressed(){
this.refs.buttonRef.setNativeProps({color:"#ffffff"});
}
I get the following error:
this.refs.buttonRef.setNativeProps is not a function. (In
'this.refs.buttonRef.setNativeProps({
color: "#ffffff"
})', 'this.refs.buttonRef.setNativeProps' is undefined)
However, if I were to define any other type of component, e.g. text input as
<TextInput ref="userInputRef" value={"this is text"} />
With the function changing its props:
buttonPressed(){
this.refs.textRef.setNativeProps({color:"#ffffff"});
}
Everything changes correctly.
Is there a reason that the button component is unable to have its native props set through setNativeProps?
Button component is a simple custom component created from Touchable components and it doesn't have a ref property. You can check the source code of Button component here.
If you need to change properties of a component you should use state values for that.
Sample
buttonPressed = () => {
this.setState({color:"#ffffff"});
}
//....
<Button ref="buttonRef" color={this.state.color} title="Button" onPress={this.buttonPressed}/>

React Navigation: Prevent multiple instances to navigate to same screen

Let's say I have this screen:
And when the user clicks on the white tooltip, it redirects to another screen. Sometimes the app lags a little bit, and clicking on the tooltip takes like ~2s to see the screen change. The problem is, during those 2s, the user taps again on this tooltip to make it happen.
And the result I get is that there are two instances of the new screen in my StackNavigator. What I mean is that I see my new screen, but when I click on "Back" I don't return to this 'Hitchhiking Map' screen, but to another instance of that same screen.
If I clicked 5 times on the callout during those 2s, then I need to click 5 times "Back" to return to the Map screen. Any way to prevent that? To put only one instance into the StackNavigator?
I am using React Navigation, more precisely a StackNavigator. Here's my code:
The "click on tooltip" part:
<MapView.Marker
onCalloutPress={() => this.props.navigation.navigate('spotDetails', { spotId: marker.id })}
/>
My screens:
const HMapNavigator = StackNavigator({
HMap: { screen: HMapViewContainer },
spotDetails: { screen: SpotDetailsViewContainer },
});
The issue of multiple navigations has been reported and there is more detail here.
react-navigation (v1.0.0-beta.7) is in beta and still being built, so until this feature is implemented, you will have to handle the debounce manually.
options
disable the button once the navigation starts
debouncing in the onPress logic or in the action if you are using redux
lodash provides a useful debounce utility, if you are looking for one.
There are many ways how to overcome double navigations.
My solution is adding a key property in navigate object:
this.props.navigation.navigate({ key: 'AnotherScreen', routeName: 'AnotherScreen', params: { ... }})}
Save if its opening to control the navigation
constructor (props) {
super(props)
this.state = {
opening: false
}
}
Create a function to control de navigation
_open (campaign) {
if (!this.state.opening) {
this.props.navigation.navigate('Campaign', {campaign})
this.setState({ opening: true })
setTimeout(() => {
this.setState({ opening: false })
}, 1000)
}
}
Call this func from your onpress
<TouchableHighlight underlayColor='transparent' onPress={this._open.bind(this, campaign)}>
In versions 1.x of React Navigation, if you specify an identifier the navigation action will be executed only once. E.g.:
navigate({ routeName: 'someScreen', key: 'someScreen', params: { someParam: 'someValue' } })
More information: https://gist.github.com/vonovak/ef72f5efe1d36742de8968ff6a708985
In versions 2.x and 3.x this is a default functionality.
More info: https://reactnavigation.org/docs/en/navigation-key.html