My HomeHeader component is like this:
import React from "react";
import { View, StyleSheet, Text, Image } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome5";
export default function HomeHeader({ navigation }) {
return (
<View style={styles.home_header}>
<Icon
style={styles.menu}
name="bars"
size={30}
color="white"
onPress={navigation.toggleDrawer()}
/>
<Image
style={styles.header_logo}
source={require("../assets/logo.png")}
/>
<Text>Hello</Text>
</View>
);
}
And am using it in my Home screen like this:
return (
<View>
<HomeHeader navigation={navigation} />
</View>
)
But am receiving this error message:
Warning: Cannot update a component from inside the function body of a
different component.
What am trying to do is, I have separated out the header section of my HOME screen into a separate component called HomeHeader. And in this component, am attaching the event handler to toggle the opening/closing of the DrawerNavigation (left side drawer menu)
If I create a Button in my HOME screen and add the event handler to toggle the drawer, it works fine. But the issue happens only if I try this from inside my HomeHeader component.
Btw, am using ReactNavigation v5 and I even tried this method: https://reactnavigation.org/docs/connecting-navigation-prop/
No luck so far.
Change onPress={ navigation.toggleDrawer() } to onPress={ ()=> navigation.toggleDrawer() }
You can read more about this in here
I'm going back to basics with React Native, as I feel overwhelmed. I have been looking for an implementation of a reusable modal component. I'm looking for examples of a reusable Modal component in RN? Thanks in advance
You can find many examples of this on StackOverflow. Still, if you need example I can help you with one example. You have mentioned modal component in your question, right?
Your component will look like this with props. let the name be ModalComponent for this file.
render() {
const { isVisible, message, textValue } = this.props;
return (
<Modal
animationType="slide"
transparent={false}
isVisible={isVisible}
backdropColor={"white"}
style={{ margin: 0 }}
onModalHide={() => {}}>
<View>
<Text>textValue</Text>
<Text>message</Text>
</View>
</Modal>
);
}
so now in your js file you need to import this modalComponent and after that, you need to write as
<ModalComponent
isVisible={true}
textValue={'hi there'}
message={'trying to make a basic component modal'}/>
Hope this will help for you
EDIT:
Create seperate components that you want to render inside modal. for Ex: component1.js, component2.js, component3.js with props
component1.js:
render(){
const { textVal, message } = this.props
return (
<View>
<Text>{textVal}</Text>
<Text>{message}</Text>
</View>
)
}
now in ModalComponent
render() {
const { first, second, third, isVisible, component1Text, component1Message } = this.props;
<Modal
animationType="slide"
transparent={false}
isVisible={isVisible}
backdropColor={"white"}
style={{ margin: 0 }}
onModalHide={() => {}}>
<View>
{first && <component1
textValue= component1Text
message= component1Message />}
{second && <Component2 />}
{third && <Component2 />}
</View>
</Modal>
In this way, you can achieve it within the single modal.
You will make a component like this giving the parent component all the liberty to change it through props.
render() {
const { isVisible, message, textValue, animationType, backDropColor, style, onModalHide, children } = this.props;
return (
<Modal
animationType= {animationType || 'slide'}
transparent={transparent || false}
isVisible={isVisible || false}
backdropColor={backdropColor || "white"}
style={[modalStyle, style]}
onModalHide={onModalHide}>
{children}
</Modal>
);
}
Then in your parent component, you need to import this component like this:
import ModalComponent from '../ModalComponent'; //path to your component
<ModalComponent isVisible={true}>
<View>
//any view you want to be rendered in the modal
</View>
</ModalComponent>
I had a lot of troubles using react-native modal, sometimes i started the app and could not close it even when i set the isVisible prop to false, it is even worst on IOs, i did a research and these packages are not being maintained properly.
You will save a lot of time by using a top-level navigator like is recommended in the modal docs: https://facebook.github.io/react-native/docs/modal.
I tried https://github.com/react-native-community/react-native-modal but had the same problems because its an extension of the original react-native modal.
I suggest you to use the react-navigation modal as described here: https://reactnavigation.org/docs/en/modal.html#docsNav
You can refer the following code to write Modal component once and use multiple times.
Write once:
import React, { Component } from 'react';
import { View, Text, Button, Modal, ScrollView, } from 'react-native';
export class MyOwnModal extends Component {
constructor(props) {
super(props);
this.state = {
}
render() {
return(
<Modal
key={this.props.modalKey}
transparent={this.props.istransparent !== undefined ? true : false}
visible={this.props.visible}
onRequestClose={this.props.onRequestClose}>
<View style={{
//your styles for modal here. Example:
marginHorizontal: width(10), marginVertical: '30%',
height: '40%', borderColor: 'rgba(0,0,0,0.38)', padding: 5,
alignItems: 'center',
backgroundColor: '#fff', elevation: 5, shadowRadius: 20, shadowOffset: { width: 3, height: 3 }
}}>
<ScrollView contentContainerStyle={{ flex: 1 }}>
{this.props.children}
</ScrollView>
</View>
</Modal>
);
}
}
Now,
You can call your Modal like following example: (By doing this, you avoid re-writing the Modal and its outer styles everytime!)
Example
<MyOwnModal modalKey={"01"} visible={true} onRequestClose={() =>
this.anyFunction()} istransparent = {true}>
<View>
// create your own view here!
</View>
</MyOwnModal>
Note: If you are in using different files don't forget to import , and also you can pass the styles as props.
(You can create/customise props too based on your requirement)
Hope this saves your time.
Happy coding!
I am a contributor of react-native-use-modal.
This is an example of creating a reusable modal in a general way and using react-native-use-modal: https://github.com/zeallat/creating-reusable-react-native-alert-modal-examples
With react-native-use-modal, you can make reusable modal more easily.
This is a comparison article with the general method: https://zeallat94.medium.com/creating-a-reusable-reactnative-alert-modal-db5cbe7e5c2b
Like a title, I want to disable a submit button (Search) on device's keyboard if text input is an empty string.
I creating a search bar and using TextInput.
How can I do this?
you should have 2 state (textSearch and buttonStatus) and check every onChangeText in TextInput props
here's a simple code I've used:
import React, {Component} from 'react';
import RN, {View, StyleSheet, Text} from 'react-native';
export default class History extends Component {
constructor(props) {
super(props);
this.state={
search:null,
disabledButton:true
}
}
render(){
return(
<View style={styles.container}>
<RN.TextInput
value={this.state.search}
onChangeText={(e)=>{
this.setState({search:e, disabledButton:e==""?true:false})
}}
/>
<RN.Button
title="Search"
disabled={this.state.disabledButton}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container:{flex:1, justifyContent:'center', alignItems:'center'}
})
this is the first time I've provided help here, so hopefully it helps someone.
The inputText should be whatever state you use to store your text.
addItem() is whatever function name you want to execute when there are enough characters.
I wanted to require the user to type more than 1 character, so adjust to your liking.
onSubmitEditing={() => {(inputText.length < 2) ? console.log('test') : addItem()}}
<TextInput
style={styles.input}
onSubmitEditing={() => {
(inputText.length < 2) ? console.log('test') : addItem()
}}
maxLength={20}
autoCorrect={false}
onChangeText={onChangeText}
placeholder={'Scavenger Hunt Item'}
value={inputText}>
</TextInput>
Current Behavior
My code:
class App extends Component {
render() {
return <Drawer /> {/* rigid scrolling effect */}
return <Stack /> {/* smooth scrolling effect if I comment above return statement */}
}
}
const Drawer = DrawerNavigator({
Feed: { screen: Feed }
})
const Stack = StackNavigator({
Feed: { screen: Feed }
})
And Feed component's render is just a bunch of lines:
render() {
return <View style={{flex:1}}>
<ScrollView>
<Text>random line...</Text>
// .. more lines to make it scrollable
</ScrollView>
</View>
}
Expected Behavior
The expected behavior is to get smooth scrolling effect in both cases. However, DrawerNavigator screen's scrolling effect is extremely rigid. When I swipe my finger quickly from up to down, it doesn't keep scrolling smoothly automatically like it should in Stacknavigator example.
How to reproduce
Create App.js file above and create a simple Feed.js component which has a bunch of lines to make ScrollView work.
Can anybody help?
Update: Live demonstration: https://snack.expo.io/Hk8Np7nPG
Try this
render() {
return (
<View style={{flex:1}}>
<ScrollView>
<View>
{Your Contnet}
</View>
</ScrollView>
</View>
)}
it is worked for me...
hope it'll also worked for you
You can Use NativeBase with standard tabs Container and Contet (like ScrollView ) Header and...
first try :
npm install native-base --save
then:
npm i
react-native link
and here is your full example code:
import React, { Component } from 'react';
import { Content , View , Text } from 'native-base'; //don't need import 'react-native' components
export default class GeneralExample extends Component {
render() {
return (
<Content >
<View>
{Your Contnet}
</View>
</Content>
)}
}
and if you wanna change the speed just ScrollView try:
<ScrollView decelerationRate={0.5}>
<View/>
</ScrollView>
in NativeBase Use THIS LINK
I was following React Native basic tutorial. Then after it ended, I tried to add a button in the code used in TextInput tutorial, following example in Button page
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, Button, View } from 'react-native';
class AwsumProjek extends Component {
constructor(props) {
super(props);
this.state = {tiText: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(tiText) => this.setState({tiText})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.tiText.split(' ').map((word) => word && 'WA').join(' ')}
</Text>
<Button
title="Press Purple"
color="#841584"
accessibilityLabel="Learn more about purple"
/>
</View>
);
}
}
AppRegistry.registerComponent('AwsumProjek', () => AwsumProjek);
Instead I got this error
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined.
Check the render method of 'AwsumProjek'.
What did I do wrong? Seeing other answer, is it something related to importing something?
I'm native android developer trying to learn React Native, and as me now, Javascript is totally unfamiliar for me.
Make sure you are using correct version of React Native. Button component was introduced in React Native version 0.37