How to use custom alert in React Native? - javascript

I've created a custom alert as a component in React Native. I used Modal to create this custom alert. My problem is, how to use it? Instead of using Alert.alert in React Native, I want to display my own alert.
Here is my Custom Alert Modal.
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import Modal from 'react-native-modal';
import styles from './style';
import Button from '../../components/Button';
export default class CustomAlert extends Component {
renderModalContent = () => (
<View style={styles.content}>
<Text style={styles.contentTitle}>{this.props.title}</Text>
<Text style={styles.contentInfo}>{this.props.content}</Text>
<View style={styles.buttonContainer}>
<Button
color={this.props.buttonColor}
text={this.props.buttonText}
onPress={this.props.buttonOnPress}
/>
</View>
</View>
);
render() {
return (
<View style={styles.container}>
<Modal
isVisible={this.props.isVisible}
backdropColor="#000000"
backdropOpacity={0.9}
animationIn="zoomInDown"
animationOut="zoomOutUp"
animationInTiming={600}
animationOutTiming={600}
backdropTransitionInTiming={600}
backdropTransitionOutTiming={600}
>
{this.renderModalContent()}
</Modal>
</View>
);
}
}
This is how I want to use it. I want to display this alert through a function. That means when function catches up with an error, I want to show my custom alert.
myFunction()
.then(() => // do something)
.catch(() => // show my custom alert);
Can you help me please to solve this problem?

set isVisible true in your catch block.
myFunction()
.then(() => // do something)
.catch((e) => this.setState({ isVisible: true }))

Related

React native useState and return statement not working together

Here whenever i click the icon it doesnt show anything. It supposed to be showing some text and when clicked again it should hide the text. Im using react native.
import React, { useState } from 'react';
import { View, Text, StyleSheet, Button, Image, TouchableOpacity} from 'react-native';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
export default function Edit(props, { navigation }) {
const [slide, setSlide] = useState(false);
const toggle = () => {
setSlide(!slide);
console.log('clicked');
return (
<View>
<Text>random</Text>
<Text>random</Text>
</View>
);
}
return (
<View>
<FontAwesome name="sliders" size={30} color="#000" onPress={() => toggle()}/>
</View>
}
After testing the only thing it shows is the console.log('clicked') message. It does not display anything else. Also the icon displays normally. Everything is working except the and the content in those tags.
Rather than returning the View from your toggle function, you actually need to display that view your view hierarchy (eg what is returned from your component).
I've demonstrated in the example by using a ternary expression -- if slide is true, it gets shown, otherwise it does not.
export default function Edit(props, { navigation }) {
const [slide, setSlide] = useState(false);
const toggle = () => {
setSlide(!slide);
console.log('clicked');
}
return (
<View>
<FontAwesome name="sliders" size={30} color="#000" onPress={() => toggle()}/>
{slide ? <View>
<Text>random</Text>
<Text>random</Text>
</View> : null}
</View>
);
}
Snack example: https://snack.expo.io/7lVezwWs7

Pass state from component to Modal?

I have a component and import it in specific screen, in this screen i have a button when clicks i open modal contain component it's a "recorder" so after i record voices i want to take this voice and save them into Parent screen as a state or something!
in the recorder component, I save voices data into state! but how can i pass it to other parent screens!?
so how can I handle it?
here is shots
Parent Screen "after click add voice I show the modal"
Parent Screen
Here's a modal contain a recorder component
Modal
CODE
Component
" I pass data to PassDataToModal state inside componentDidMount "
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import {AudioRecorder, AudioUtils} from 'react-native-audio';
import Sound from 'react-native-sound';
import Icon from 'react-native-vector-icons/MaterialIcons';
class RecorderScreen extends Component {
state = {
PassDataToModal: null,
};
componentDidMount() {
AudioRecorder.requestAuthorization().then(isAuthorised => {
this.setState({hasPermission: isAuthorised});
AudioRecorder.onFinished = data => {
console.log('data', JSON.stringify(data));
this.setState({PassDataToModal: data});
};
});
}
render() {
return (
<View style={styles.container}>
<View style={styles.controls}>
{this._renderPlayButton(() => {
this._play();
})}
{this._renderRecordButton(this.state.recording)}
{this._renderStopButton('Stop', () => {
this._stop().then(() => this.setState({currentTime: 0}));
})}
</View>
<Text style={styles.progressText}>{this.state.currentTime}s</Text>
</View>
);
}
}
export default RecorderScreen;
Parent Screen
import Modal from 'react-native-modal';
import RecorderScreen from './Recorder';
class Order extends Component {
constructor(props) {
super(props);
this.state = {
isModalVisible: false,
};
}
toggleModal = () => {
this.setState({isModalVisible: !this.state.isModalVisible});
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={this.toggleModal}
>
<Icon name="mic" color="#333" size={20} />
<Text style={{paddingHorizontal: 5}}>Add Voice</Text>
</TouchableOpacity>
<Modal
style={{margin: 0}}
isVisible={this.state.isModalVisible}
>
<View>
<TouchableOpacity onPress={this.toggleModal}>
<Icon name="close" color="#000" size={25} />
</TouchableOpacity>
<RecorderScreen /> // Component
</View>
</View>
)
}
}
In your parent component pass a function to your RecorderScreen component that will send the necessary data up. Docs on lifting state up.
So in your parent you'd have something like:
setData = (data) => {
// Set this to whatever you need it to be named
this.setState({childData: data});
}
Then pass the function as a prop:
<RecorderScreen setData={this.setData} />
And finally, call it in the child however needed (If I'm following the code something like this):
componentDidMount() {
AudioRecorder.requestAuthorization().then(isAuthorised => {
this.setState({hasPermission: isAuthorised});
AudioRecorder.onFinished = data => {
this.props.setData(data);
};
});
}
Then your parent component will have access to the child's data that you have lifted up.

How to use HoC with React Native

I have an listing app where users can add items for multiple categories, when they want to add new record, there are 3 related screens with this particular feature. All of those screens have <Header/> component, so i thought HoC would be nice here so that i can reuse it across 3 screens.
However, i could not accomplish it.
Here is what i tried so far:
This is my HoC class
import React, { Component } from 'react';
import { View, StyleSheet, Text, StatusBar } from 'react-native';
import Header from '../components/Header';
const NewAd = (WrappedComponent) => {
class NewAdHoc extends Component {
handleBackPress = () => {
this.props.navigation.navigate('Home');
StatusBar.setBarStyle('dark-content', true);
}
render() {
const {contentText, children} = this.props
return (
<View style={styles.container}>
<Header
headerText={'Yeni ilan ekle'}
onPress={this.handleBackPress}
/>
<View style={styles.contentContainer}>
<Text style={styles.contentHeader}>{contentText}</Text>
<WrappedComponent/>
</View>
</View>
);
}
}
return NewAdHoc;
}
this is my screen:
class NewAdScreen extends Component {
render() {
const Content = () => {
return (
<View style={styles.flatListContainer}>
<ListViewItem />
</View>
);
}
return (
NewAdHoc(Content)
)
}
}
after that i am getting error
TypeError: (0 , _NewAdHoc.NewAdHoc) is not a function(…)
and i have no idea how can i fix it because this is my first time using hocs on a react-native app. I have looked why this error is popping and they suggest import components in this way:
import {NewAdHoc} from '../hocs/NewAdHoc';
but even this is not solved it.
any help will be appreciated, thanks.
The main purpose of a HOC is to encapsulate and reuse stateful logic across components. Since you are just reusing some jsx and injecting nothing in WrappedComponent you should be using a regular component here:
const NewAd = ({ contentText, children }) => {
handleBackPress = () => {
this.props.navigation.navigate('Home');
StatusBar.setBarStyle('dark-content', true);
}
return (
<View style={styles.container}>
<Header
headerText={'Yeni ilan ekle'}
onPress={this.handleBackPress}
/>
<View style={styles.contentContainer}>
<Text style={styles.contentHeader}>{contentText}</Text>
{children}
</View>
</View>
);
}
And use it like this
return(
<>
<NewAd>
<Screen1 />
</NewAd>
<NewAd>
<Screen2 />
</NewAd>
<NewAd>
<Screen3 />
</NewAd>
</>
)

Adjacent JSX elements must be wrapped in an enclosing tag React Native

I'm a beginner in React Native trying to test out TouchableOpacity. I keep getting this error code 'Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...? (16:4)'
The issue seems to be at the opening TouchableOpacity tag.
I've already tried putting fragments around it but it didn't work does anyone know how I fix this??
import React from 'react';
import { Text, StyleSheet, View, Button, TouchableOpacity } from 'react-
native';
const HomeScreen = () => {
return (
<View>
<Text style={styles.text}>Sup boiz</Text>
<Button
onPress={() => console.log('Button pressed')}
title="Go to components demo"
/>
<TouchableOpacity onPress={ () => console.log('List Pressed')>
<Text>Go to List demo</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
text: {
fontSize: 30
}
});
export default HomeScreen;
<TouchableOpacity onPress={ () => console.log('List Pressed')}>
<Text>Go to List demo</Text>
</TouchableOpacity>
Simple syntax error. It should be onPress={ () => console.log('List Pressed')}
You missed }

How to connect react component in react navigation?

I have created modal in react native. I have added filter option icon in top right corner now when the user clicks on it should open the modal. How can I do that ? I have added Options icon in navigation.js but now how to connect it with modal component ?
In code below setModalVisible is available in filteroptions.js and not in navigation.js
Code:
navigation.js:
Updates: {
screen: UpdatesScreen,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Myapp',
headerRight:<TouchableOpacity onPress={() => {this.setModalVisible(true);}}>
<MenuIcon style={{paddingLeft: 10, paddingRight: 15}} name="md-options" size={25} color="white"/>
</TouchableOpacity>,
})
},
filteroptions.js:
import React, {Component} from 'react';
import {Modal, Text, TouchableHighlight, View, Alert} from 'react-native';
export default class FilteroptionsModel extends Component {
state = {
modalVisible: false,
};
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</View>
);
}
}
When user clicks on filter button in top right corner (see screenshot) he should be able to see the box modal on screen:
Since it is a modal you don't necessarily need to add it to the navigation. You can just include it in your page and initially have it be invisible, then when the user clicks your button you can make the modal visible. But if you want to add it to the navigation why not just add like any other component. However, adding it to the navigation will take you to another page when you navigate to the component. Of course you can add a nested navigator to work around that, but I think it adds unnecessary complexity.
Update
You will first declare a Header component.
export default class MyHeader extends React.PureComponent {
render() {
<View>
<View>...Your left Icon here</View>
<View>...Your Title here</View>
<View>...Your right Icon Here</View>
</View>
}
}
Then in your page you will render this component first, pass as props your handlers and then render the rest of the page.
export default class MyPage extends React.PureComponent {
yourRigthHandler = () => {
this.setState({modaVisible: true});
}
yourLeftHandler = () => {....}
render() {
<View>
<MyHeader
LeftHandler={yourLeftHandler}
LeftHandler={yourRigthHandler}>
....
</MyHeader>
</View>
}
}
inside the handlers you can call the navigation functions to navigate to another page or change the components state to make the moda visible.The handlers will be passed as props to your header and you will add them as onPress handlers to your buttons.

Categories