How to write Custom flash message in react native - react-native

I want to display a custom message after successful record update when boolean value of recordUpdateSuccess become true and after 3seconds it should disappear.
{recordUpdateSuccess ? this.renderRecordUpdatedSucess() : null}
I have function to display message:
renderRecordUpdatedSucess = () => (
<View style={styles.sucessAlert}>
<Text style={styles.sucessAlert}>Record updated successfully.</Text>
</View>
)
I tried to use setTimeout() to display message but not working.
Any idea to acheive this one.
I don't want to use Toast, any third party library for this one.

Custom flash message (No external Library)
Working Example: https://snack.expo.io/#msbot01/1dcddc
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flashMessage: false
}
}
onPress(){
this.setState({
flashMessage: true
},()=>{setTimeout(() => this.closeFlashMessage(), 3000)})
}
closeFlashMessage(){
this.setState({
flashMessage: false
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>{this.onPress()}}>
<Text>Click Me</Text>
</TouchableOpacity >
{this.state.flashMessage==true?
<View style={styles.flashMessage}>
<Text style={{color:'white'}}>This is custom Flash message</Text>
</View>
:
null
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flashMessage:{
position:'absolute',
backgroundColor:'green',
width:'100%',
justifyContent:'center',
alignItems:'center',
height:40,
top:0
}
});

Related

I need to fix bug with react native. what is the problem?

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
import React, { PureComponent, useState } from 'react'
import { StoryContainer } from 'react-native-stories-view'
import {
TouchableOpacity,
Alert,
StyleSheet,
View,
Text,
SafeAreaView,
ImageBackground,
Image,
Platform,
StatusBar,
} from 'react-native'
import { connect } from 'react-redux'
class StoryViewScreen extends PureComponent {
constructor(props) {
super(props);
this.state = {
}
}
render() {
const { files } = this.props.route.params;
const fileUrls = [];
for (var i = 0; i < files.length; i++) {
fileUrls.push(files[i].uri);
}
console.log("files path:", fileUrls);
return (
<View style={{ flex: 1, flexDirection: 'column' }}>
{Platform.OS === 'ios' && (
<View style={{
backgroundColor: 'gray',
height: 45,
}}>
<StatusBar barStyle="light-content" backgroundColor={'green'} />
</View>
)}
{Platform.OS === 'android' && (
<StatusBar barStyle="dark-content" backgroundColor={'white'} />
)}
<SafeAreaView style={{ flex: 1, flexDirection: 'column', backgroundColor: 'gray' }}>
<StoryContainer
visible={true}
enableProgress={false}
images={fileUrls}
duration={5}
containerStyle={{
width: '100%',
height: '100%',
}} />
{/* <Text>This is teh realdksfjdsklfj</Text> */}
</SafeAreaView>
</View>
);
}
};
const style = StyleSheet.create({
});
function mapStateToProps(state) {
return {
// currentUser: state.user.currentUser,
};
}
function mapDispatchToProps(dispatch) {
return {
dispatch
};
}
export default connect(mapStateToProps, mapDispatchToProps)(StoryViewScreen);
You cannot use useState in class component, instead use setState to set the state.

Error: Element type is invalid: expected a string (for build-in components) or a class/function... - REACT NATIVE

I got this error while working on my Content.js file:
Before this everything was fine so I know it's not App.js or another file.
I've tried 'npm install' just in case... Most people online that experienced similar errors mention that it might have to do with the way the component is exported but I already changed it to 'export default class Content extends Component' just like most people suggested.
This is the file:
Content.js
import React, { Component } from "react";
import { StyleSheet, View, ActivityIndicator, ScrollView, Card, Text} from 'react-native';
import firebase from '../../firebase';
export default class Content extends Component {
constructor() {
super();
this.state = {
isLoading: true,
article: {},
key: ''
};
}
componentDidMount() {
const ref = firebase.firestore().collection('articles').doc('foo');
ref.get().then((doc) => {
if (doc.exists) {
this.setState({
article: doc.data(),
key: doc.id,
isLoading: false
});
} else {
console.log("No such document!");
}
});
}
render() {
if(this.state.isLoading){
return(
<View style={styles.activity}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
)
}
return (
<ScrollView>
<Card style={styles.container}>
<View style={styles.subContainer}>
<View>
<Text h3>{this.state.article.title}</Text>
</View>
<View>
<Text h5>{this.state.article.content}</Text>
</View>
</View>
</Card>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20
},
subContainer: {
flex: 1,
paddingBottom: 20,
borderBottomWidth: 2,
borderBottomColor: '#CCCCCC',
},
activity: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
},
})
You have imported Card from the react-native but React native does not provide Card component inbuilt.

React-Native Constructor

Please help me find what is wrong in the following React-Native code?
It says after constructor (props) should have ';' semicolon. I don't know if I declared it in the right way.
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default function App() {
constructor (props){
this.state = {
text: 'HI'
}
}
render () {
return (
<View style={styles.container}>
<TextInput style={styles.input}
placeholder = 'Enter Value...'
placeholderTextColor ='#E74292'
onChangeText = {(text) => {
this.setState({text})
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:'#F4C724',
},
input :{
marginTop:30,
height:30,
width:30,
borderWidth:2,
padding:10,
borderRadius: 5,
borderColor:'#1287A5'
}
}
);
You should declare the component as class instead of function if you want a constructor:
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App {
constructor(props) {
this.state = {
text: 'HI'
};
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Enter Value..."
placeholderTextColor="#E74292"
onChangeText={text => {
this.setState({ text });
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F4C724'
},
input: {
marginTop: 30,
height: 30,
width: 30,
borderWidth: 2,
padding: 10,
borderRadius: 5,
borderColor: '#1287A5'
}
});
constructor only works in class based component so switch to class based component rather than . functional whihc is now.
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App extends React.Component{
constructor(props) {
this.state = {
text: 'HI'
};
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Enter Value..."
placeholderTextColor="#E74292"
onChangeText={text => {
this.setState({ text });
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F4C724'
},
input: {
marginTop: 30,
height: 30,
width: 30,
borderWidth: 2,
padding: 10,
borderRadius: 5,
borderColor: '#1287A5'
}
});
You need to study the difference between functional and class component.
Functional component is just a plain java-script function which also known as stateless component. They do not manage their own state or have access to the lifecycle methods.
for more please follow the link below:
https://medium.com/#Zwenza/functional-vs-class-components-in-react-231e3fbd7108
you can use useState , the dynamic function value loads to the initial variable on load
import React,{ useState } from 'react';
import { View, Text, Button, ImageBackground} from 'react-native';
export default function Home({navigation}){
//function getversion onload
const [initval,setInitval] = useState(()=>{ return '123456'});
return(
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text> {initval} </Text>
</View>
);
}
You cannot have a constructor() in functional components. You should either change function component to class component or go and check out the react doc about React Hooks. You are going to have a better understanding of the differences between react class components and react functional components.

Two of my common components that I'm importing with index.js don't fire

I'm doing this course at Udemy. Files: https://github.com/StephenGrider/ReactNativeReduxCasts/tree/master/auth
The issue I'm having is with importing common components. It's only for 2 of the common components--the rest work fine. Card, CardSection, Header, Input.
When I try to import the Button or Spinner, they won't fire. But if I use the basic functionality (putting the TouchableOpacity or ActivityIndicator in the file directly and do all the styling THERE), they work fine.
Here's the file structure:
Here's /components/common/index.js
export * from './Header';
export * from './Input';
export * from './Card';
export * from './CardSection';
export * from './Button';
export * from './Spinner';
Here's Button.js
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const Button = ({ propOnPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={propOnPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
)
}
const styles = {
textStyle: {
alignSelf: 'center',
color: '#fff',//'#007aff',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10
},
buttonStyle: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: '#007aff', //'#fff',
borderRadius: 5,
borderWidth: 1,
borderColor: '#007aff',
marginLeft: 5,
marginRight: 5,
}
}
export { Button };
Here's Spinner.js
import React from 'react';
import { View, ActivityIndicator } from 'react-native';
const Spinner = ({ size }) => {
return (
<View style={styles.spinnerStyle}>
<ActivityIndicator size={size || 'large'} />
</View>
)
}
const styles = {
spinnerStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
}
export { Spinner }
Here's where I import them in LoginForm.js
import { Card, CardSection, Button, Spinner, Input } from './common';
And where they're used in the code in LoginForm.js
renderButton() {
//console.log('render button');
if (this.state.loading) {
console.log('returning the spinner');
return <Spinner animating={this.state.loading} size="small" />;
}
console.log('gonna return a button');
return(
<Button onPress={this.onYouPressedIt.bind(this)}>Log in</Button>
);
}
What am I doing wrong?
Issues I see with the Button.js file
Property onPress doesn't exist. You created a property called propOnPress
So, your Button component should be used like this
<Button propOnPress={}>...</Button>
Issues I see with the Spinner.js file
Property animating doesn't exist on the component. The only properties you created is size.
Solution would be to simply add an animating property to your Spinner component.
Component would end up looking like this
const Spinner = ({ animating, size }) => {
return (
{
animating ? (
<View style={styles.spinnerStyle}>
<ActivityIndicator size={size || 'large'} />
</View>
) : null
}
)
}
I assume the animating property is a boolean which if false then you don't want to display the activity indicator which is why I added the ternary operator.

Open a WebView after a button pressed with reactNative

I am developing a mobile app with React Native. I want to open a WebView after a button pressed. Here is my code, but its not working. The button onPress method is not working.
import React, { Component } from 'react';
import { View, StyleSheet, Button, WebView } from 'react-native';
import { Constants } from 'expo';
export default class webView extends Component {
onNavigationStateChange = navState => {
if (navState.url.indexOf('https://www.google.com') === 0) {
const regex = /#access_token=(.+)/;
const accessToken = navState.url.match(regex)[1];
console.log(accessToken);
}
};
renderContent() {
return (
<WebView
source={{
uri: '',
}}
onNavigationStateChange={this.onNavigationStateChange}
startInLoadingState
scalesPageToFit
javaScriptEnabled
style={{ flex: 1 }}
/>
);
}
render() {
return (
<View style={styles.container}>
<Button
style={styles.paragraph}
title="Login"
onPress={() => this.renderContent()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
I tried onPress={this.renderContent()} this also, but it give an exception. What can I do ?
You aren't rendering your WebView in the the render() method of the Component. Just think of render as your DOM of the webpage. You need to provide the component a place in the render component, than you can remove it or add it, see i am calling the renderContent from the render method. So whenever the state variable showWebView is true it will render the WebView You should do something like this:
import React, { Component } from 'react';
import { View, StyleSheet, Button, WebView } from 'react-native';
import { Constants } from 'expo';
export default class webView extends Component {
state={
showWebView: false
}
onNavigationStateChange = navState => {
if (navState.url.indexOf('https://www.google.com') === 0) {
const regex = /#access_token=(.+)/;
const accessToken = navState.url.match(regex)[1];
console.log(accessToken);
}
};
renderContent() {
return (
<WebView
source={{
uri: '',
}}
onNavigationStateChange={this.onNavigationStateChange}
startInLoadingState
scalesPageToFit
javaScriptEnabled
style={{ flex: 1 }}
/>
);
}
render() {
return (
<View style={styles.container}>
{ this.state.showWebView && this.renderContent() }
<Button
style={styles.paragraph}
title="Login"
onPress={() => this.setState({showWebView: true})}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
I think you must import the following
import { WebView } from 'react-native-webview'
instead of
'react'