I currently working in a React Native project using 'https://www.npmjs.com/package/react-native-raw-bottom-sheet' lib to handle bottom up panel.
I want to trigger bottom up panel everytime I click a button in parent component instead of clicking a button in child component, how do I can achieve this.
Bottom Up Panel child component:
const refRBSheet : any = useRef();
View style={styles.container}>
<View style={{width:200}}>
<Button title="OPEN BOTTOM SHEET" onPress={() => refRBSheet.current.open()} />
</View>
<RBSheet
ref={refRBSheet}
closeOnDragDown={true}
closeOnPressMask={true}
animationType='slide'
customStyles={{
wrapper: {
backgroundColor: "transparent"
},
draggableIcon: {
backgroundColor: "#999999"
},
container:{
backgroundColor:'#101010',
height:450,
}
}}
>
<MyComponent/>
</RBSheet>
</View>
My parent component:
<View>
<Button title="I want to click this button and trigger ButtomUpPanel/>
<BottomUpPanel/>
</View>
You need to use the useImperativeHandle hook in your parent
const refRBSheet : any = useRef();
const open = () => {
refRBSheet.current.open()
};
useImperativeHandle(refRBSheet, () => ({
open,
}));
Then pass the ref down to your components.
<View>
<Button onPress={()=>open()} title="I want to click this button and trigger ButtomUpPanel/>
<BottomUpPanel ref={refRBSheet} />
</View>
Remember useImperativeHandle should be used with forwardRef.
Actually after hours of researching I finally found a way for my own question:
To pass a ref to child component from parent component I use
forwardRef
By importing import
{forwardRef} from 'react';
Then in my case i just wrap my child component in forwardRef:
const DetailPanelBottomUp: FC<IDetailPanel> = forwardRef(
({imgUrl, title, contentUrl,value}, ref: any) => {
return (
<View style={styles.container}>
<RBSheet
ref={ref}
onClose={() => setSocialNet(false)}
closeOnDragDown={true}
closeOnPressMask={true}
animationType="slide"
customStyles={{
wrapper: {
backgroundColor: 'transparent',
},
draggableIcon: {
backgroundColor: '#999999',
},
container: {
backgroundColor: '#101010',
height: 450,
},
}}>
<MyComponent/>
</RBSheet>
</View>
And in my parent component I just declare
useRef
and its action then pass the ref to child component as a props
const refRBSheet : any = useRef();
const open = () => {
refRBSheet.current.open();
};
<View>
<DetailPanelBottomUp title={actionItem.title} contentUrl={actionItem.src} ref=
{refRBSheet} imgUrl={actionItem.src} />
<Button onPress={()=>open()} title="I want to click this button and trigger ButtomUpPanel/>
</View>
Related
I have added a picture on the bottom of the mobile screen with style as:
bottomView: {
position: 'absolute',
bottom: 0,
},
Above this picture, I have my sign-in form, but because the picture is at the absolute position, it is not letting the keyboard open. I don't want to make this picture relative as it will disturb the picture. Can anyone help me in such a way that I want to keep the picture on the bottom too but want to open the keyboard as well.
Complete code is:
import React from "react";
import { Image, StyleSheet, Text, View ,TextInput,KeyboardAvoidingView} from "react-native";
import Authentication_Button from "./Authentication_Button";
import { SocialIcon } from 'react-native-elements'
const Login = () => {
const [email, setEmail] = React.useState('');
const [password, setPassword] = React.useState('');
return(
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container} enabled>
{/* <View style={styles.container}> */}
<Image source={require('./assets/Logo.png')} style={styles.logo}/>
<TextInput
label="Email"
value={email}
onChangeText={email => setEmail(email)}
style={styles.TXT_INPUT}
placeholder="Email"
/>
<TextInput
label="Password"
value={password}
onChangeText={password => setPassword(password)}
style={styles.TXT_INPUT}
placeholder="Password"
/>
<View style={styles.auth}>
<Authentication_Button title={"Login"} backGroundColor={"#2c88d1"} textColor = {"#FFFFFF"} borderColor={"#2c88d1"}/>
<Authentication_Button title={"Signup"} backGroundColor={"#FFFFFF"} textColor = {"#2c88d1"} borderColor={"#2c88d1"}/>
</View>
<Text>- OR -</Text>
<Text>Sign in with </Text>
<SocialIcon
raised={true}
type='google'
style={{backgroundColor:"#2c88d1"}}
/>
<KeyboardAvoidingView style={styles.bottomView}>
<Image source={require('./assets/footLogin.png')} />
</KeyboardAvoidingView>
{/* </View> */}
</KeyboardAvoidingView>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor:"#effdfe",
justifyContent:"center",
alignItems:"center",
padding:20
},
logo :{
width:150,
height:150,
resizeMode:'cover'
},
TXT_INPUT:{
marginBottom:10,
marginTop:10,
borderRadius:12,
borderWidth:1.4,
width:"85%",
paddingVertical:14,
backgroundColor:"#ffffff",
color:"#000000",
fontSize:18
},
auth:{
marginTop:10,
marginBottom:10,
width:"85%",
},
bottomView: {
marginTop:'5%',
position: 'absolute', //Here is the trick
bottom: 1, //Here is the trick
},
});
export default Login;
You can use KeyboardAvoidingView as a parent view. It will help you either your internal button or view is an absolute position
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
</KeyboardAvoidingView>
So the issue has been resolved. The issue was that the footer image was basically on top ofthe text input fields so as soon I changed the positions, it started to work!
Am building a carousel project using react native,
the code worked perfectly when i used only images ,before adding the sections "image" "title" in data
I get this error "Error while updating property 'src' of a view managed by: RCTImageView" after this code , i tried many possible methods but still no result.
import * as React from 'react';
import { StatusBar, FlatList, Image, Animated, Text, View, Dimensions, StyleSheet, TouchableOpacity } from 'react-native';
const { width, height } = Dimensions.get('screen');
const data = [
{imageUrl:'https://images.unsplash.com/photo-1509023464722-18d996393ca8?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80',
title: "Hope"},
{imageUrl:'https://images.unsplash.com/photo-1494587351196-bbf5f29cff42?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1051&q=80',
title: "Hope2"},
{imageUrl:'https://images.unsplash.com/photo-1439792675105-701e6a4ab6f0?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1052&q=80' ,
title: "Hope3"}
];
export default () => {
const scrollX=React.useRef(new Animated.Value(0)).current;
return (
<View >
<StatusBar hidden />
<View
style={StyleSheet.absoluteFillObject}>
{data.map((image,index)=>{
const inputRange=[
(index -1)*width,
index*width,
(index+1)*width
]
const opacity = scrollX.interpolate({
inputRange,
outputRange:[0,1,0]
})
return <Animated.Image
key={'image-${index}'}
source={{uri:image}}
style={[
StyleSheet.absoluteFillObject,
{opacity}
]}
/>
})}
</View>
<Animated.FlatList
data={data}
onScroll={Animated.event(
[{nativeEvent:{contentOffset:{x:scrollX}}}],
{useNativeDriver: true}
)}
keyExtractor={(_,index)=> index.toString()}
renderItem={({item})=> {
return <View >
<Text style={{color:'white'}}> {item.title} </Text>
<Image source={{uri:item.imageUrl}}
/>
</View>
}}
/>
</View>
);
};
Try this. Update source in Animated.Image to image.ImageUrl instead of just "image"
<Animated.Image
key={'image-${index}'}
source={{uri:image.imageUrl}}
style={[
StyleSheet.absoluteFillObject,
{opacity}
]}
/>
How can I set the cursor position in a TextInput field with a button and still be able to change the position normally by pressing on a certain point on the text?
You have to keep track of your selection manually (done through selection and onSelectionChange properties):
export default function App() {
const [text, setText] = React.useState("test")
const [selection, setSelection] = React.useState({start:0, end: 0})
return (
<View style={{flex: 1, justifyContent: 'center'}}>
<TextInput
style={{borderWidth: 1}}
value={text}
onChangeText={newText => setText(newText)}
selection={selection}
onSelectionChange={({ nativeEvent: { selection, text } }) => setSelection(selection)}
/>
<Button
title="Press me"
onPress={() => {
setSelection({start: 2, end: 2})
}}
/>
</View>
);
}
I am new to React Native. If I asked something so easy sorry 'bout that.
I have Picker Component in my App.js.
I want to go to component depending on a Picker item.
So, for example; I picked the second item of Picker, when I Clicked the 'Next' button it has to go to second.js
Here is some Part of my Code:
My App.js:
...
...
function Third({ navigation }) {
return (
<View style={styles.container}>
<Text style={styles.circle}>2</Text><Text style={styles.titles}>Operating Mode</Text>
<Text />
<Text style={styles.description}>Please select operating mode</Text><Text/>
<Picker/>
<Button title="Next" style={styles.buttons} color="#FF7F11" onPress={() => navigation.navigate("Fourth")}/><Text/>
<Button title="Back" style={styles.buttons} color="#FF7F11" onPress={() => navigation.goBack()} /><Text/>
</View>
);
}
...
...
and my Picker.js:
import React, { Component } from "react";
import { Text, View, StyleSheet } from "react-native";
import { Picker } from "#react-native-picker/picker";
class Picker extends Component {
state = {router: ''}
updaterouter = (router) => {
this.setState({ router: router })
}
render() {
return (
<View>
<Picker selectedValue={this.state.router} style={styles.drop} onValueChange = {this.updaterouter}>
<Picker.Item label="Rt" value="rt" />
<Picker.Item label="Ap" value="ap" />
<Picker.Item label="Rp" value="rp" />
<Picker.Item label="Wp" value="wp" />
</Picker><Text></Text>
</View>
);
}
}
export default Picker
const styles = StyleSheet.create({
drop: {
height: 30,
width: 200,
backgroundColor: "#FFF"
}
})
One option is to pass the value to the parent via a callback function, something like this:
updaterouter = (router) => {
this.setState({ router: router })
props.onRouterUpdated && props.onRouterUpdated(router)
}
<Picker onRouterUpdated={(r)=>{/*do something with r*/}}/>
Another would be to use common store (e.g. Redux)
I'm trying to implement a custom navigation drawer using react-navigation and react-native-elements. I also want all my screens to have a header (that has a hamburger from which I can control the drawer). The problem I'm facing is that the screen includes the header, while the drawer includes the screen, yet the header needs the drawer for its click event. So how do I pass the drawer object to my hamburger (inside the header component)?
The header in the file UniversalHeader.js is as follows
export default class UniversalHeader extends React.Component {
render() {
return (
<Header
leftComponent={{ icon: 'menu', color: '#ea0', onPress: () => this.props.navigation.navigate('DrawerToggle'), size: 50}}
centerComponent={{ text: this.props.label, style: { color: '#fff' } }}
/>
);
}
}
In my home screen, I have
import UniversalHeader from './UniversalHeader'
export default class HomeScreen extends React.Component {
render() {
return (
<View>
<UniversalHeader />
<Text> cards go here </Text>
</View>
);
}
}
Then in the compiling script collating the screens, I have
import HomeScreen from './home';
class customNav extends React.Component {
render() {
return (
<View>
<Avatar rounded xlarge source={require('./images/logo.png')} />
<DrawerNavigatorItems navigation={{state: [{routeName: 'Home', key: '0'}]}}
items={['Home', 'Discussions', 'Podcasts', 'Sermons', 'Events']}
onItemPress={route => this.props.navigation.navigate(route)}
renderIcon={(routeIcon) => (
<Image source={{uri: `./images/${routeIcon}.png`}} style={[styles.icon, {/*tintColor: tintColor*/}]} />
)}
getLabel={route => route.toString()}
/>
</View>
)
}
}
const MyApp = DrawerNavigator({
Home: {
screen: HomeScreen
}
}, {drawerBackgroundColor: '#000', contentComponent: customNav});
The onPress method in Header leftComponent has no idea of who navigator is but I don't know how to get it across either from the screen 'home.js' or from the 'UniversalHeader.js'.
The navigation property is automatically added to every component passed as a screen to any react-navigation component. So by proactively passing this.props.navigation of homescreen component to universalHeader i.e
<UniversalHeader navigation={this.props.navigation} />
You'll be giving it the navigator that's aware of all your registered classes/screen (in this case, passed into DrawerNavigator)