React native, using TouchableOpacity onPress - react-native

I just started learning react native. I am currently trying to implement TouchableOpacity on image rendering from an array and use the info for that element from the array to create a new page. The goal of the code is to have a userInfo page that lists all the images and once you tap on an image, it will show details of that user (you will see just this user and no other ones) using userDetails. I know my TouchableOpacity part will not work, but I don't know how to make it work.
This is from my userInfo.js:
const UserInfo =() => {
const users = [
{userName: "A",
imageSource: require("../../assets/users/A.jpg"),
bio: "this is A"
},
{userName: "B",
imageSource: require("../../assets/users/B.jpg"),
bio: "this is B"
},
{userName: "C",
imageSource: require("../../assets/users/C.jpg"),
bio: "this is C"
}
]
return(
<FlatList
showsVerticalScrollIndicator={false}
keyExtractor={(users)=> users.userName}
data={users}
renderItem = {({item})=>{
return <View>
<TouchableOpacity onPress={userInfoLink(users.userName, users.imageSource, users.bio)}>
<View style={styles.viewBox}><Image style={styles.image} source={item.imageSource}/></View>
</TouchableOpacity>
<Text style={styles.text}>{item.userName}</Text>
</View>;
}}
/>
)
};
This is from my userDetails.js:
const UserDetail=({imageSource, userName, bio}) => {
return <View>
<View style={styles.viewBox}><Image style={styles.image} source={imageSource}/></View>
<Text style={styles.text}>User name: {userName}</Text>
<Text style={styles.text}>Bio: {bio}</Text>
</View>;
}

Ok, after doing some research I found a way to make it work. I used navigation.navigate and passing parameters into the page.
Here is my return code in UserInfo.js:
return(
<FlatList
showsVerticalScrollIndicator={false}
keyExtractor={(users)=> users.userName}
data={users}
renderItem = {({item})=>{
return <View>
<TouchableOpacity onPress={()=>{navigation.navigate('UserDetails', {imageSource: item.imageSource, userName: item.userName, bio:item.bio })}}>
<View style={styles.viewBox}><Image style={styles.image} source={item.imageSource}/></View>
</TouchableOpacity>
<Text style={styles.text}>{item.userName}</Text>
</View>;
}}
/>
)
Here is the code in UserDetails.js:
const UserDetail=({navigation}) => {
const imageSource = navigation.getParam('imageSource', 'a no image image');
const userName = navigation.getParam('userName', 'username error');
const bio = navigation.getParam('bio', 'bio error');
return <View>
<Text style={styles.title}>User Detail</Text>
<View style={styles.viewBox}><Image style={styles.image} source={imageSource}/></View>
<Text style={styles.text}>User name: {userName}</Text>
<Text style={styles.text}>Bio: {bio}</Text>
<Button title="User Info" onPress={()=>{navigation.navigate('UserInfo')}}/>
</View>;
}

I am wondering if adding the parenthesis and arrow was what fixed it.
You went from:
onPress={userInfoLink(users.userName, users.imageSource, users.bio)}
To this:
onPress={()=>{navigation.navigate('UserDetails', {imageSource: item.imageSource, userName: item.userName, bio:item.bio })}}

Related

How to use hooks as image's source in react native?

Im making this menu that when the user clicks at an option, it changes the background image, but i cant use the hook that i created as a parameter to the source of the image. Can someone find where im wrong and how to fix it?
Heres the part of my code referents to the menu and the hooks:
export function Home(){
let imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
}
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const [skin, setSkin] = useState('vovo')
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
useEffect(() => {
if(param==1){
setSkin('vovo');
}
else if(param==2){
setSkin('mc');
}
else if(param==3){
setSkin('pato');
}
})
return(
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={handleAbout}>
<Counter />
</TouchableOpacity>
<TouchableOpacity onPress={() => {
setShowBottomSheet(true)
}}
>
<Image source={skin} style={styles.imgvj}/>
</TouchableOpacity>
<BottomSheet show={showBottomSheet} height={290} onOuterClick={hide}>
<Pressable onPress={hide} style={styles.bottomSheetContent}>
<Image source={barrinhaLoja} style={styles.barra}/>
</Pressable>
<View style={styles.conteudoLoja}>
<View style={styles.marginLeft48}>
<TouchableOpacity onPress={() => {
setParam(1);
}}>
<Image source={vovoJuju} style={styles.vovo}/>
<Text style={styles.legendasLoja}>Vovó Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(2);
}}>
<Image source={mcJuju} style={styles.mc}/>
<Text style={styles.legendasLoja}>MC Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(3);
}}>
<Image source={patoJuju} style={styles.pato}/>
<Text style={styles.legendasLoja}>Pato Juju</Text>
</TouchableOpacity>
</View>
</View>
</BottomSheet>
I created the "let imagens", "const param", "const skin" and the "useEffect trying" to make this function. I already tried using the source in different ways such as source={skin} and source={imagens[skin]} but it havent worked.
I'm not certain if this solves your problem, but here's how the first few lines of your component should look like without useEffect:
const imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
};
export function Home(){
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
let skin = 'vovo';
switch(param) {
case 1: skin = 'vovo'; break;
case 2: skin = 'mc'; break;
case 3: skin = 'pato'; break;
}
return /* the rest goes here */
}
To reference the actual image, you would use something like {imagens[skin]}.
I moved imagens outside of this function because it never changes, but it doesn't impact anything otherwise.

TouchableOpacity link to another page and pass data React Native

Hi i am hitting to a problem. In the Homepage, I am creating a list of cards where show name, amount, and image, and those cards are created by another function from InfoCard.js.
Now I am not sure how to pass the data ( name, amount) and link to another page
Homepage:
import InfoCard from "../components/test";
const Home = ({ navigation }) => {
return (
{data.map((item, index) => (
<InfoCard {...item} key={index} />
))}
);
};
export default Home;
InfoCard js
export default InfoCard = ({ image, brand, amount }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate("Detail")}>
<View style={externalStyle.home_company_list}>
<Image source={image} />
<View style={externalStyle.card}>
<Text style={externalStyle.home_company_text}>{brand}</Text>
<Text style={externalStyle.home_company_text}>{amount}</Text>
</View>
</View>
</TouchableOpacity>
);
};
Detail Page
Once the TouchableOpacity clicked from home page which created by InFoCard.js, will pass the data(brand,amount) to Detail page and display the data
You can pass it as params:
export default InfoCard = ({ image, brand, amount }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate("Detail", {brand: brand,
amount: amount,})}>
<View style={externalStyle.home_company_list}>
<Image source={image} />
<View style={externalStyle.card}>
<Text style={externalStyle.home_company_text}>{brand}</Text>
<Text style={externalStyle.home_company_text}>{amount}</Text>
</View>
</View>
</TouchableOpacity>
);
};
And get it in details as:
this.props.navigation.state.params.brand,
this.props.navigation.state.params.amount
You can simply pass the parameter after the "Detail" Route name.
Take a look here: https://reactnavigation.org/docs/params/

How to make a card clickable to navigate to another screen in REACT NATIVE

here is the code to the card I need to make clickable as I need to navigate to a new screen and pass parameters to it upon clicking on the card:
function ItemV({ title, url,verificationId,AttReq}) { //for verification items
return (
<TouchableOpacity
onPress={() => navigation.navigate('VerificationRequestDetails',
{
item:AttReq,
img : url ,
name : title,
verificationId:verificationId
,})}
style={[
styles.item,
{ backgroundColor:'#ffffff' },
]}
>
<Card title="Verification Request">
<View style={styles.item}>
<Image source={{ uri: url }} style={styles.image} />
<Text style={styles.title}>{title}</Text>
</View>
<Text style={styles.paragraph}>You are required to verify this information</Text>
</Card>
</TouchableOpacity>
);
}

I am using react-native-swiper-flatlist , but I cannot figure it out how to use scrollToIndex on button press

I am using react-native-swiper-flatlist , I want to scroll forward to some index by tapping button but no clue how to do it. Although I am very beginner to react native development.
I have searched alot but nothing helps, I get an error of undefined is not an object this2.swiper.scrollToIndex'
render() {
return (
<View style={styles.container}>
<SwiperFlatList
ref={swiper => {
this.swiper = swiper;
}}
data={[
{ key: "a" },
{ key: "b" },
{ key: "c" },
{ key: "d" },
{ key: "e" }
]}
index={0}
renderItem={({ item, index }) => (
<View>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Button
title={"Next"}
onPress={this.swiper.scrollToIndex(1, true)}
style={{ backgroundColor: "white" }}
/>
</View>
)}
/>
</View>
);
}
Should swipe on button click
Here is the screenshot of the error I am getting
Try adding ref='swiper' as a SwiperFlatList prop,
Example
<SwiperFlatList ref='swiper'/>
this.refs.swiper._scrollToIndex(2)
For those who are using React hook instead of class, you can do sth like that to utilise the scrollToIndex function
//First, make a ref for storing the swiper instance inside your swiper compoent
const swiperRef = useRef<any>({});
//Second, store the reference
<SwiperFlatList
ref={(component) => { swiperRef.current._swiper = component; }}
>
//Later on, you can call the function like this
swiperRef.current._swiper.scrollToIndex({index: 2})

React Native clear text multiple TextInput boxes

I found example code on a facebook React Native page which shows how to use setNativeProp to clear text on a click but I can't see how to do it with multiple text boxes. Here is the code:
var App = React.createClass({
clearText() {
this._textInput.setNativeProps({text: ''});
},
render() {
return (
<View style={styles.container}>
<TextInput ref={component => this._textInput = component}
style={styles.textInput} />
<TouchableOpacity onPress={this.clearText}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
});
The ref seems to be fixed in the function so will always target the same TextInput box. How can I alter the function to target any TextInput box I indicate?
This should work. Notice that the ref on the TextInput needs to be the one you call from the clearText functino.
var App = React.createClass({
clearText(fieldName) {
this.refs[fieldName].setNativeProps({text: ''});
},
render() {
return (
<View style={styles.container}>
<TextInput ref={'textInput1'} style={styles.textInput} />
<TouchableOpacity onPress={() => this.clearText('textInput1')}>
<Text>Clear text</Text>
</TouchableOpacity>
<TextInput ref={'textInput2'} style={styles.textInput} />
<TouchableOpacity onPress={() => this.clearText('textInput2')}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
});
Updated my answer to clear different fields.
You can also use something like this to clear the text of TextInput.
clearText(fieldName) {
this.refs[fieldName].clear(0);
},