React Native from child component to parent with StackNavigator - reactjs

How I do to navigate from child component to parent?
YoutubeVideo.js
<YouTube
videoId={this.state.VideoId}
play={false}
loop={false}
apiKey={apikey}
onReady={e => this.setState({ isReady: true })}
onChangeState={e => this.setState({ status: e.state })}
onChangeQuality={e => this.setState({ quality: e.quality })}
onError={e => this.setState({ error: e.error })}
style={{ alignSelf: 'stretch', height: 250 }}
/>
<Related videoId={this.state.VideoId} />
</View>
RelatedComponent.js
<View>
<ScrollView>
<RkCard rkType='shadowed' >
{this.state.data.map((item, i) =>
<TouchableHighlight
key={item.id.videoId}
onPress={() => props.navigate('YoutubeVideo', {youtubeId:item.id.videoId})}>
<View rkCardContent>
<Image rkCardImg
source={{uri: item.snippet.thumbnails.medium.url}}
style={styles.image}/>
<View style={styles.vidItems}>
<Text style={styles.vidText}>{item.snippet.title}</Text>
<Icon name='more-vert' size={20} color='#555'/>
</View>
</View>
</TouchableHighlight>
)}
</RkCard>
</ScrollView>
</View>
I want to send new Youtube ID from related videos but its same page.

You don't need to navigate again to YoutubeVideo. you can pass videoID by a callback to parent like this:
RelatedComponent.js
...
<TouchableHighlight
onPress={() => {this.props.onVideoClick(item.id.videoId)} }
>
...
YoutubeVideo.js
...
<Related
videoId={this.state.VideoId}
onVideoClick={(videoID) => { this.setState({ VideoId: 'videoID' }) }}
/>
...
You can send data to parent by this way. I hope this will help you

Related

Cannot render the function icons inside flatlist - React Native

icons are not coming.Alert is working.Cannot render the function icons inside flatlist.
pls help.I need your help.
myCode:
<FlatList
data={this.state.data}
//extraData={}
keyExtractor={(item, index) => {
return index.toString();
}}
renderItem={({ item }) =>
<View style={styles.cartView}>
<TouchableOpacity style={styles.touchView} onPress={() => Linking.openURL(item.app_link)}>
<Image style={styles.cartLogo} source={{ uri: item.app_resim }} />
</TouchableOpacity>
<Text style={styles.mainViewText}>{item.app_name}</Text>
<View style={styles.mainViewAltBar}>
<TouchableOpacity >
<Icon name="refresh-outline" size={30} color="#404040" />
</TouchableOpacity>
{this.appSet(item.app_namep)}
</View>
</View>
} />
appSet(value){
AppInstalledChecker.isAppInstalledAndroid(value)
.then((isInstalled) => {//not show icons but alert working
if (isInstalled) {
return (<Icon name="checkmark-outline" size={30} color="#404040" />);
} else {
return (<Icon name="close-outline" size={30} color="#404040" />);
//alert(isInstalled);
}
})
}
Thank you.

How to pass Parent Flatlist's Index value to Child Flatlist's onPress function?

How to pass parent Flatlist's index value to child Flatlist's function so I can use it in function and change value by setState.
So how to pass parent Flatlist's index value to child Flatlist's function so I can use it in function and change value by setState.
It starts with a list that built-in state
constructor(props) {
super(props);
this.state = {
list: [
{
question: 'il veicolo ha la gomma forata?',
answers: [
{
radioButtonValue: false,
text: strings.CONFIRMVIEW_yes,
},
{
radioButtonValue: true,
text: strings.CONFIRMVIEW_no,
},
],
},
]
}
}
checkBoxSelection = (item, index) => {
// if (item.radioButtonValue == index) {
// this.list.answers[index].radioButtonValue = true
// }
console.log(this.state.list[0].answers[index].radioButtonValue)
}
_renderItem = ({ item, index }) => {
return (
<View style={styles.cellView}>
<Text style={styles.questionText}>
{item.question.toUpperCase()}
</Text>
<FlatList
data={item.answers}
horizontal={true}
showsHorizontalScrollIndicator={true}
scrollEnabled={true}
bounces={false}
renderItem={this._renderItemOptions}
/>
{/* <View style={styles.yesNoRadioButtonView}>
<View style={styles.yesChekboxView}>
<TouchableOpacity onPress={ () => {console.log("TEST1"); this.checkBoxSelection()} }>
<Image source={(item.answers == index) ? AppImages.radioOn : AppImages.radioOff} style={styles.radioButton} />
</TouchableOpacity>
<Text style={styles.yesNoText}>
{strings.CONFIRMVIEW_yes}
</Text>
</View>
<View style={styles.noRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection.bind(this) }}>
<Image source={(item.answers == 0) ? AppImages.radioOn : AppImages.radioOff} style={styles.radioButton} />
</TouchableOpacity>
<Text style={styles.yesNoText}>
{strings.CONFIRMVIEW_no}
</Text>
</View>
</View> */}
</View>
)
}
_renderItemOptions = ({ item, index }) => {
return (
<View>
<View style={styles.yesNoRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection(item, index) }}>
<View style={styles.yesChekboxView}>
<Image
source={item.radioButtonValue ? AppImages.radioOn : AppImages.radioOff}
style={styles.radioButton}
/>
<Text style={styles.yesNoText}>
{item.text}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
render() {
return (
<Container>
<Content style={styles.container}>
<FlatList
data={this.state.list}
showsVerticalScrollIndicator={false}
scrollEnabled={false}
bounces={false}
renderItem={this._renderItem}
/>
</Content>
<SafeAreaView>
<TouchableOpacity
style={[LayoutStyle.appBtn1]}
>
<Text style={[LayoutStyle.appBtnText1]}>
{strings.DAMAGE_SURVEY_comeOn.toUpperCase()}
</Text>
</TouchableOpacity>
</SafeAreaView>
</Container>
)
}
In Parent Flatlist's renderItem function
replace
renderItem = { () => {this.renderItemOptions(item, index)}}
with
renderItem={(childData) => this._renderItemOptions(childData, index)}
and then in child Flatlist's renderItemOption function need to get parentIndex with another name.
_renderItemOptions = ({ item, index }, parentIndex) => {
console.log("hello")
return (
<View>
<View style={styles.yesNoRadioButtonView}>
<TouchableOpacity onPress={() => { this.checkBoxSelection(item, index, parentIndex) }}>
<View style={styles.yesChekboxView}>
<Image
source={item.radioButtonValue ? AppImages.radioOn : AppImages.radioOff}
style={styles.radioButton}
/>
<Text style={styles.yesNoText}>
{item.text}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
Try updating your renderItem prop in your FlatList to explicitly pass the index
renderItem={({item, index}) => this._renderItemOptions(item, index)}

how to show loading only for one item in flatlist?

i'm getting a list of products and i show it in a flatlist. when somebody wants to add quantity of an item or remove an item i will show a loading only on that specific card.
i shouldn't add property to list object models.
const Counter = ({ quantity, itemId }) => {
console.log(quantity);
console.log('ITEM ID ',itemId);
return (
<View style={{flexDirection:'row', alignItems:'center'}}>
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:25}} name='md-trash' onPress={()=> removeItem(itemId)} />
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:10}} name='md-remove'/>
<View style={{marginRight:10, alignItems:'center',justifyContent:'center'}}>
<CustomText value={`${numTranslate(quantity)}`} style={{color:'#059b9a', fontSize:22, fontWeight:'bold'}}/>
<CustomText style={{fontSize:10}} value={'حداکثر'} />
</View>
<Icon style={{fontSize: 25, color: '#059b9a', marginRight:10}} name='md-add' />
</View>
);
}
i only want to show loading instead of last icon until fetch response comes.
You need some kind of prop that shows rather or not your data has fetched yet. Since you did not attach your data fetch, i will just assume, that you can add it to your component.
const Counter = ({ quantity, itemId, isLoading }) => {
console.log(quantity);
console.log('ITEM ID ',itemId);
//declare conditional constant for icon
const icon = isLoading ? <div><p>Loading...</p></div> : <Icon style={{fontSize: 25, color: '#059b9a', marginRight:10}} name='md-add' />
return (
<View style={{flexDirection:'row', alignItems:'center'}}>
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:25}} name='md-trash' onPress={()=> removeItem(itemId)} />
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:10}} name='md-remove'/>
<View style={{marginRight:10, alignItems:'center',justifyContent:'center'}}>
<CustomText value={`${numTranslate(quantity)}`} style={{color:'#059b9a', fontSize:22, fontWeight:'bold'}}/>
<CustomText style={{fontSize:10}} value={'حداکثر'} />
</View>
{/* render conditional expression instead of jsx element */}
{icon}
</View>
);
}
your main component where using Counter :
// Call setState here or anywhere you want to fetch data or...
fetchData =()=> {
this.setState({isLoading: true});
axios.post(url).then(response=>{
this.setState({isLoading: false});
})
}
render(){
return(
<Counter quantity={quantity} itemId={itemId} isLoading={this.state.isLoading} />
)
}
your Counter object:
const Counter = ({ quantity, itemId, isLoading }) => {
console.log(quantity);
console.log('ITEM ID ',itemId);
return (
<View style={{flexDirection:'row', alignItems:'center'}}>
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:25}} name='md-trash' onPress={()=> removeItem(itemId)} />
<Icon style={{fontSize: 25, color: '#059b9a',marginRight:10}} name='md-remove'/>
<View style={{marginRight:10, alignItems:'center',justifyContent:'center'}}>
<CustomText value={`${numTranslate(quantity)}`} style={{color:'#059b9a', fontSize:22, fontWeight:'bold'}}/>
<CustomText style={{fontSize:10}} value={'حداکثر'} />
</View>
{isLoading ?
<LoadingIcon />
:
<Icon style={{fontSize: 25, color: '#059b9a', marginRight:10}} name='md-add' />
}
</View>
);
}
1) Maintain an array in the state like loadingItems. In the onPress, push the itemId into loadingItems before the try block. whether if the call succeed or not, pop the itemId that is within the try or catch block.
2) Add a loading prop to your component and check if the itemId is in the loadingItems array.
<Card
isLoading={this.state.loadingItems.includes(item.Id)
...
/>
Hope this helps.
Create a new variable loadingItem.
Store the itemId in loadingItem before you call your fetchData method
Check if loading is true and itemId equals loadingItem
{loading && itemId === loadingItem ? <LoadingIcon />
:
<Icon style={{fontSize: 25, color: '#059b9a', marginRight:10}} name='md-add' />
}

React Native child component not rendering on onPress event

I am trying to render the child component on onPressevent, the console.log works fine but components in the return function doesn't works.
Parent component:
onPress = (img,title,content) => {
this.setState({
show:true,
img:img,
title:title,
content:content
})
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<TouchableOpacity
onPress={() => this.onPress(item.urlToImage,item.title,item.content)}
>
<View style={styles.picsCont}>
<Image style={styles.pics} source={{uri: item.urlToImage}}/>
<Text style={{color:'white', fontSize: 15, fontWeight: '700', paddingTop:10}}>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.title}
/>
{this.state.show ?
<NewsView
img={this.state.img}
title={this.state.title}
content={this.state.content}
/> :
null
}
</View>
);
}
}
Child Component:
export default class NewsView extends Component {
render() {
console.log(this.props.img)
return (
<View style={styles.container}>
<Image style={styles.picsCont} source={{uri:this.props.img}} />
<Text style={styles.news}>{this.props.title}</Text>
<Text style={styles.news}>{this.props.content}</Text>
</View>
)
}
}
Thanks for the help...!
It might be the styles. If your child component has position:'absolute', it´s probably under your parent component, you can try to put on your child component view zIndex:10

How to close the modal in react native

I am newbie to react native developing. I want to close the modal component on pressing outside the modal in reactnative. Below is my code.
state = {
visibleModal : false,
};
_hideModal(){
this.setState({
visibleModal: true,
})
}
render(){
return(
<View style={
[styles.container,
{backgroundColor: this.state.visibleModal ? 'rgba(47, 60, 73, 0.75)': 'white'}
]}>
<Text>Text Behind Modal</Text>
{ this._renderButton('BUTTON', () => this.setState({ visibleModal: true}) ) }
<TouchableWithoutFeedback onPress={() => {this._hideModal()}}>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<View style={styles.modalContent}>
<Row />
</View>
</Modal>
</TouchableWithoutFeedback>
</View>
);
}
}
Just add this prop in Modal
onRequestClose={() => { this.visibleModal(false); } }
It will close your modal on pressing back button
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}
onRequestClose={() => { this.visibleModal(false); } }
>
EDIT
Above code will work only on Android as per the document.
For both,
You can add custom button to close modal
<TouchableOpacity
onPress={() => {
this.setState({visibleModal: false})
} }>
<Image
style={[styles.modalBackIcon]}
source={require('../../theme/images/back-icon.png')} />
</TouchableOpacity>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<TouchableWithoutFeedback onPress={() => {this.close_modal()}}>
<View style={styles.modalContent}>
....
</View>
</TouchableWithoutFeedback>
</Modal>
this is sample of my code when you tap outside to close your modal
than so close_modal function visibleModal get false value
for exp.
this.setState({ visibleModal: false });
Question :
To close modal when clicking outside the modal.
Solution:
Just remove function call on TouchableWithoutFeedback,it will work..
<TouchableWithoutFeedback onPress={() => {}}>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<View style={styles.modalContent}>
<Row />
</View>
</Modal>
</TouchableWithoutFeedback>

Resources