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/
Related
I am making an app where anyone can join a fantasy golf tournament. On my homepage there is a flatlist which is receiving data from api. There will be many tournaments but the user can only join the upcoming one. Now what i want to do is disable the functionality of every other tournament that means there is a join button through which user can join so i want to disable every other button and only enable the upcoming tournament button. What should i do?
here's my code
const Item = ({ title, location, date, Id }) => (
<View style={styles.renderItemView}>
<View style={styles.imageView}>
<Image style={styles.imageView2} source={require('../../assets/golf.png')} />
</View>
<View style={styles.TextView}>
<Text style={styles.Text}>Name: {title}</Text>
<Text style={styles.Text}>Location: {location}</Text>
<Text style={styles.Text}>StartDate: {moment(date).format('DD-MM-YYYY')}</Text>
<Text style={styles.Text}>Contest Fee: $49</Text>
</View>
<View style={styles.JoinView}>
<TouchableOpacity onPress={() =>{
navigation.navigate('Join', {key:Id, date});
}} style={styles.Touch1}>
<Text style={styles.JoinText}>Join</Text>
</TouchableOpacity>
</View>
</View>
);
const renderItem = ({ item }) => (
<View>
<Item title={item.name} location={item.location} date={item.startDate} Id={item.Id} />
</View>
);```
You could use row index and modulus operator to define the disabled prop like this:
const renderItem = ({ item, index }) => (
<View>
<Item title={item.name} disabled={index % 1 === 1} location={item.location} date={item.startDate} Id={item.Id} />
</View>
);`
And the use it in the Item component on the TouchableOpacity like this:
const Item = ({ disabled }) => (
<View>
...other stuff
<TouchableOpacity disabled={disabled} />
</View>
)
<TouchableOpacity disabled={props.disabled} />
i have two different API and i want show two API in one Flatlist this is worked (look the picture). i show it using filter by id API (if API have same id will show). My question is how to remove/hide/dont show null value flatlist (look the picture)?
Im using API from https://jsonplaceholder.typicode.com
picture my app
const {user, post} = useSelector(state => state.reducer);
const dispatch = useDispatch();
const getData = [...user, ...post];
useEffect(() => {
dispatch(getProfile());
dispatch(getPost());
}, []);
const tailwind = useTailwind();
const renderPost = ({item}) => {
const renUsr = user.filter(renUsr => renUsr.id === item.userId);
return (
renUsr.id !== item.userId ? (
<View style={tailwind('pb-4')}>
<View style={tailwind('px-4 py-4 bg-gray-200 mx-6 rounded-[20px]')}>
<View style={tailwind('flex flex-row')}>
<Image style={tailwind('rounded bg-black w-8 h-8')} />
{renUsr.map(posting => (
<Text
key={posting.id}
style={tailwind('pl-2 font-semibold py-2')}>
{posting.name}
</Text>
))}
</View>
<View style={tailwind('mt-2')}>
<TouchableHighlight
style={styles.touchHighlight}
onPress={navigation}>
<View style={tailwind('bg-gray-200 p-1')}>
<Text key={item.id}>{item.body}</Text>
</View>
</TouchableHighlight>
</View>
</View>
</View>
) : (
null
)
);
};
return (
<FlatList
data={getData}
renderItem={renderPost}
keyExtractor={item => item.id}
/>
);
};
user.filter(renUsr => renUsr.id === item.userId);
Instead of using the filter here, just filter the list passed to the flatlist so you it will be looped only once and you don't to filter for every single item
I have two different components "HomePage" & "ListItemCA"
In HomePage, I have a FlatList and a modal popup
<FlatList
data={ listData}
keyExtractor={list => list.Title}
renderItem={({ item }) => <ListItemCA data={item} onLongPress={openModal} />}
/>
and each list item is called from another component ListItemCA
function ListItemCA({data, onLongPress}) {
return (
<TouchableOpacity onLongPress={onLongPress} >
<View style={styles.container}>
<Text style={styles.title}>{data.Title}</Text>
<View style={styles.metaContainer}>
<Text style={styles.meta}>{( data.totalMonths != null ? data.totalMonths : '0' )} Months</Text>
<Text style={styles.meta}>{( data.members != null ? data.members.length : '0' )} Members</Text>
</View>
</View>
</TouchableOpacity>
);
}
What I want to acheive?
I want to get the selected list item title on my HomePage component. When a user longpress on a list item that title should be displayed on a modal popup. How do I pass the selected list item title to the HomePage component using longpress?
If your goal is to display data from the long pressed item in the modal, you could add the data as a parameter of your openModal function:
function openModal(data) {
// your function
return (
<Text>{data.Title}</Text>
)
}
Then, in your FlatList, modify the props of ListItemCA to call openModal for the selected item:
renderItem={({ item }) => <ListItemCA data={item} onLongPress={openModal(item)} />}
If you also want to save the data from the long pressed item in your HomePage component for other uses, you could save it in the state. In your HomePage component:
import React, { useState } from 'react'
function HomePage() {
const [itemData, setItemData] = useState()
// your code
}
Then, in your flatlist:
<FlatList
data={listData}
keyExtractor={list => list.Title}
renderItem={({ item }) =>
<ListItemCA
data={item}
onLongPress={ () => {
setItemData(item)
openModal(item)
}}
/>
}
/>
You can achieve this by passing(return) parameter from your component like this -
function ListItemCA({data, onLongPress}) {
return (
<TouchableOpacity onLongPress={() => {
onLongPress(data.Title);
//return data.Title when onLongPressed clicked
}}>
<View style={styles.container}>
...
</View>
</TouchableOpacity>
);
}
then get it in props -
<FlatList
data={listData}
keyExtractor={list => list.Title}
renderItem={({ item }) =>
<ListItemCA
data={item}
onLongPress={(title) => {//this **title** return from **onLongPress(data.Title)**
openModal();
setTitle(title);// or directly can pass that title in openModal func.
}}
/>
}
/>
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 })}}
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);
},