I am working on an app by react native.i have a problem. when my app has a debug mode work very well. but in without debug mode, my Flatlist is not rendering all items.
I'm using redux and redux-saga
class ComponentGroups extends React.Component {
constructor (props){
super(props)
this.state = {
listBanner: this.props.item.listBanner
}
}
eventOnscroll = () => {
console.log('load list banner pls what wrong with u')
}
checkRenderView = () => {
if(this.state.listBanner.length && this.state.listBanner.length === 1) {
return (
<ComponentBanner item={this.state.listBanner[0]} typeTab={1}/>
)
}
const dimensions = Dimensions.get('window');
const screenWidth = dimensions.width;
return (
<ScrollView onScroll={this.eventOnscroll}>
<FlatList
style={{
flex: 1,
width: screenWidth
}}
showsHorizontalScrollIndicator={false}
horizontal={true}
data={this.state.listBanner}
removeClippedSubviews={false}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <ComponentBanner item={item} index={index} typeTab={1}/>}
/>
</ScrollView>
)
}
render () {
return (
<View style={styles.bannerItem}>
{this.state.listBanner.length && this.checkRenderView()}
</View>
)
}
}
and my component item:
class ComponentBanner extends React.Component {
constructor (props) {
super(props)
}
handlePressDetailBanner = () => {
detailImageScreen({item: this.props.item, typeTab: 1})
}
showViewNewsViewed = () => {
if(this.props.item.hot && this.props.item.watched) {
return (
<View style={styles.viewsLiked}>
<View style={styles.iconLike}>
<Text style={styles.news}>Mới</Text>
</View>
<View style={styles.iconView}>
<Text style={styles.viewed}>Đã xem</Text>
</View>
</View>
)
}
if(this.props.item.hot && !this.props.item.watched) {
return (
<View style={styles.viewsLiked}>
<View style={styles.iconLike}>
<Text style={styles.news}>Mới</Text>
</View>
</View>
)
}
if(!this.props.item.hot && this.props.item.watched) {
return (
<View style={styles.viewsLiked}>
<View style={styles.iconView}>
<Text style={styles.viewed}>Đã xem</Text>
</View>
</View>
)
}
}
render () {
return (
<View style={styles.bannerItem}>
<TouchableOpacity onPress ={this.handlePressDetailBanner}>
<Image source={{uri: this.props.item.url}} style={styles.imageItem} borderRadius={5} resizeMode='stretch'/>
</TouchableOpacity>
<View style={styles.titleLikes}>
{this.showViewNewsViewed()}
<Text numberOfLines={2} ellipsizeMode='tail' style={styles.textTitle}>{this.props.item.name}</Text>
<View style={styles.viewsLiked}>
<View style={styles.iconLike}>
<Icon
name='thumb-up'
color={this.props.item.userLike? Colors.mpAdvertise : Colors.cloud}
size={Fonts.size.regular}
/>
<Text style={styles.accountLike}>{this.props.item.totalLike}</Text>
</View>
<View style={styles.iconView}>
<Icon
name='eye'
color={Colors.cloud}
size={Fonts.size.regular}
/>
<Text style={styles.accountLike}>{this.props.item.totalView}</Text>
</View>
</View>
</View>
</View>
)
}
}
export default ComponentBanner
and Render Item by :
render () {
return (
<TouchableOpacity onPress ={this.handlePressDetailBanner} style={styles.detailImage}>
<View style={styles.bannerItem}>
<View>
<Image source={{uri: this.props.item.url ? this.props.item.url : ''}} style={styles.imageItem} borderRadius={5} resizeMode='stretch'/>
</View>
<View style={styles.titleLikes}>
<Text numberOfLines={2} ellipsizeMode='tail' style={styles.textTitle}>{this.props.item.name ? this.props.item.name : ''}</Text>
<View style={styles.viewsLiked}>
<View style={styles.iconLike}>
<Icon
name='thumb-up'
color={this.props.item.userLike? Colors.mpAdvertise : Colors.cloud}
size={Fonts.size.regular}
/>
<Text style={styles.accountLike}>{this.props.item.totalLike ? this.props.item.totalLike : ''}</Text>
</View>
<View style={styles.iconView}>
<Icon
name='eye'
color={Colors.cloud}
size={Fonts.size.regular}
/>
<Text style={styles.accountLike}>{this.props.item.totalView ? this.props.item.totalView : ''}</Text>
</View>
</View>
</View>
</View>
</TouchableOpacity>
)
}
}
UPDATE: sorry for forgot main screen rendering ComponentGroups:
constructor (props) {
super(props)
this.state = {
params: {
SourceType: '',
GroupCode: '',
NumOfRec: 10,
PageNum: 1,
TypeId: '',
},
data:[],
groupBanner: '',
groupVideo: '',
mainBanner: '',
listBanners: [],
listVideos: [],
isSelected: 1,
fetching: false,
onEndReachedCalledDuringMomentum: true
}
Navigation.events().bindComponent(this)
this.props.getData()
}
static getDerivedStateFromProps(nextProps, prevState){
if (nextProps.fetching !== prevState.fetching){
return {
fetching: nextProps.fetching,
data: nextProps.data,
listBanners: nextProps.listBanners,
listVideos: nextProps.listVideos
}
}
else return null;
}
componentDidUpdate(prevProps, prevState) {
if (prevState.fetching !== this.state.fetching) {
}
}
componentDidAppear () {
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
enabled: true
}
}
})
}
showSideMenu () {
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: true
}
}
})
}
navigationButtonPressed ({ buttonId }) {
this.showSideMenu()
}
handlePressScroll = () => {
const {params} = this.state
if(!this.state.fetching) {
this.setState({
params: {
...params,
PageNum: params.PageNum + 1,
}
}, () => {
const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
console.log(data)
if(this.state.isSelected === 2) {
this.props.getDataBanner(data)
}
if(this.state.isSelected === 3) {
this.props.getDataVideo(data)
}
})
} else {
return null
}
}
handlePressSwitchTab = (value) => {
this.setState({
isSelected: value,
params: {
SourceType: 1,
GroupCode: '',
NumOfRec: 10,
PageNum: 1,
TypeId: 0
},
listBanners: [],
listVideos: [],
},()=>{
if(value === 1) {
this.props.resetStateHome()
this.props.getData()
}
if(value === 2) {
this.props.resetStateHome()
const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
this.props.getDataBanner(data)
}
if(value === 3) {
this.props.resetStateHome()
const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
this.props.getDataVideo(data)
}
})
}
formatData = (data, numColumns) => {
const numberOfFullRows = Math.floor(data.length / numColumns)
let numberOfElementsLastRow = data.length - (numberOfFullRows * numColumns)
while (numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0) {
data.push({ key: `blank-${numberOfElementsLastRow}`, empty: true })
numberOfElementsLastRow++
}
return data
}
handlePressBanner = () => {
detailImageScreen({item: this.state.data.mainBanner})
}
eventScroll = () => {
console.log(45544)
}
renderViewByState = () => {
const numColumns = 2;
if(this.state.data && this.state.data.mainBanner && this.state.data.mainBanner.url) {
var url = this.state.data.mainBanner.url
}
if (this.state.isSelected === 1) {
if(this.state.fetching) {
return (
<View style={styles.styleLoadMore}>
<BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
</View>
)
} else {
return (
<ScrollView onScroll={this.eventScroll} >
<View style={styles.centered}>
<TouchableOpacity onPress={this.handlePressBanner} style={styles.mainBannerImage}>
<Image source={{uri: url}} style={styles.logo} borderRadius={5} resizeMode='stretch'/>
</TouchableOpacity>
</View>
<View style={styles.containerContent}>
<View style={styles.sectionBanner} >
<View>
<Text style={styles.textBanner}>BANNERS</Text>
</View>
<View style={styles.listBanner}>
<FlatList
data={this.state.data.groupBanner}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <ComponentGroups item={item} index={index} />}
/>
</View>
</View>
<View style={styles.sectionBanner} >
<View>
<Text style={styles.textBanner}>VIDEOS</Text>
</View>
<View style={styles.listBanner}>
<ScrollView>
<FlatList
data={this.state.data.groupVideo}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <ComponentGroupsVideo item={item} index={index} />}
/>
</ScrollView>
</View>
</View>
</View>
</ScrollView>
)
}
}
if (this.state.isSelected === 2) {
if(this.state.fetching && this.state.params.PageNum < 2) {
return (
<View style={styles.styleLoadMore}>
<BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
</View>
)
}
return (
<ScrollView onScroll={this.eventScroll}>
<View style={styles.listBanner}>
<FlatList
extraData={this.state}
ListFooterComponent = {this.renderFooter}
data={this.state.listBanners}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <BannerItem item={item} index={index}/>}
numColumns={countNumber}
onEndReached={this.handlePressScroll}
onEndReachedThreshold={0.05}
/>
</View>
</ScrollView>
)
}
if (this.state.isSelected === 3) {
if(this.state.fetching && this.state.params.PageNum < 2) {
return (
<View style={styles.styleLoadMore}>
<BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
</View>
)
}
return (
<View style={styles.listBanner}>
<FlatList
extraData={this.state}
data={this.state.listVideos}
ListFooterComponent = {this.renderFooter}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <VideosItem item={item} index={index} typeTab={3}/>}
numColumns={countNumber}
onEndReached={this.handlePressScroll}
onEndReachedThreshold={0.01}
/>
</View>
)
}
}
renderFooter = () => {
if(this.state.fetching && this.props.isStopScroll && this.state.params.PageNum > 1) {
return (
<View style={styles.styleLoadMoreFooter}>
<BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
</View>
)
}
return null
}
render () {
return (
<View style={styles.mainContainer} testID='launchScreen'>
<View style={styles.tabBarHome}>
<View style={[styles.itemTab, this.state.isSelected === 1 ? styles.itemTabActive : null]}>
<TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(1)}>
<View style={styles.loginButton}>
<Text style={[styles.itemText, this.state.isSelected === 1 ? styles.itemTextActive : null]}>Nổi bật</Text>
</View>
</TouchableOpacity>
</View>
<View style={[styles.itemTab, this.state.isSelected === 2 ? styles.itemTabActive : null]}>
<TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(2)}>
<View style={styles.loginButton}>
<Text style={[styles.itemText, this.state.isSelected === 2 ? styles.itemTextActive : null]}>Banner</Text>
</View>
</TouchableOpacity>
</View>
<View style={[styles.itemTab, this.state.isSelected === 3 ? styles.itemTabActive : null]}>
<TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(3)}>
<View style={styles.loginButton}>
<Text style={[styles.itemText, this.state.isSelected === 3 ? styles.itemTextActive : null]}>Videos</Text>
</View>
</TouchableOpacity>
</View>
</View>
{this.renderViewByState()}
</View>
)
}
}
const mapStateToProps = (state) => {
return {
data: state.home.data,
listBanners: state.home.listBanners,
listVideos: state.home.listVideos,
fetching: state.home.fetching,
cart: state.login.dataCart,
isStopScroll: state.home.isStopScroll
}
}
const mapDispatchToProps = (dispatch) => {
return {
getData: () => dispatch(HomeActions.homeRequest()),
getDataBanner: (data) => dispatch(HomeActions.bannerRequest(data)),
getDataVideo: (data) => dispatch(HomeActions.videoRequest(data)),
resetStateHome: () => dispatch(HomeActions.resetStateHome())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)
The above code, render my item in flatlist .in debug mode working very good, but in release mode, it's not rendering at all
please try this
<FlatList
style={{
flex: 1,
width: screenWidth
}}
extraData={this.state} //<--- add this line
showsHorizontalScrollIndicator={false}
horizontal={true}
data={this.state.listBanner}
removeClippedSubviews={false}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => <ComponentBanner item={item} index={index} typeTab={1}/>}
/>
Related
I am trying to retrieve a list of products from my API. For the moment, nothing is displayed, the page is currently empty except for my back button and I do not understand why. The two functions I use are functional since both console.log works. Could you help me ?
Everything looks fine, the console.log work in the terminal but I can't display anything in the app.
I tried this snack : https://snack.expo.io/O4oPj8-Qz
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.productItem, style]}>
<Text style={[styles.h4, {textAlign: "left"}]}>
{item.name}
</Text>
</TouchableOpacity>
);
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {
selectedId: '',
setSelectedId: '',
listData: '',
currentPage: 1,
loadMoreVisible: true,
loadMoreVisibleAtEnd: false,
displayArray: null
}
};
initListData = async () => {
let list = await getProducts(1);
console.log(list)
if (list) {
this.setState({
displayArray: list,
loadMoreVisible: (list.length >= 15 ? true : false),
currentPage: 2
});
}
};
setNewData = async (page) => {
let list = await getProducts(parseInt(page));
if (list) {
this.setState({
displayArray: this.state.displayArray.concat(list),
loadMoreVisible: (list.length >= 15 ? true : false),
loadMoreVisibleAtEnd: false,
currentPage: parseInt(page)+1
});
}
};
loadMore() {
this.setNewData(this.state.currentPage);
}
displayBtnLoadMore() {
this.setState({
loadMoreVisibleAtEnd: true
});
}
async UNSAFE_componentWillMount() {
this.initListData();
}
render() {
return (
<View>
{this.state.displayArray !== null && this.state.displayArray.length > 0 ? (
<View style={{ flex: 1, marginBottom: 100 }}>
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.displayArray}
extraData={this.selectedId}
onEndReached={() => this.displayBtnLoadMore()}
renderItem={({item})=>
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('ProductDetails', {productId: parseInt(item.id)})}
/>
</View>
}
keyExtractor={item => "product-" + item.id.toString()}
style={{width:"90%"}}
/>
{this.state.loadMoreVisible === true && this.state.loadMoreVisibleAtEnd === true ? (
<Button title=" + " onPress={()=>{this.loadMore()}}></Button>
) : null
}
<View style={styles.container}>
<Text>{"\n"}</Text>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
back
</Text>
</View>
</TouchableOpacity>
</View>
<Text>{"\n\n"}</Text>
</SafeAreaView>
</View>
) : (
<View style={styles.container}>
<Text>{"\n\n" + (this.state.displayArray === null ? i18n.t("products.searching") : i18n.t("products.nodata")) + "\n\n\n"}</Text>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
Back
</Text>
</View>
</TouchableOpacity>
</View>
)}
</View>
);
};
}
You were not adding flex: 1 and also not calling the API in the right way, here is the snack with the solution.
Link to snack
Thanks to your answers and help. I got it work this way : Thank you so much for yout time and help, really, sincerely.
import React, { Component } from "react";
import { FlatList, SafeAreaView, Button, Text, View, TouchableOpacity } from 'react-native';
import { getProducts } from '../../../src/common/Preferences';
import styles from '../../../assets/styles';
import i18n from '../../../src/i18n';
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.productItem, style]}>
<Text style={[styles.h4, {textAlign: "left"}]}>
{item.name}
</Text>
</TouchableOpacity>
);
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {
selectedId: '',
setSelectedId: '',
listData: '',
currentPage: 1,
loadMoreVisible: true,
loadMoreVisibleAtEnd: false,
displayArray: []
}
};
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
loadMoreVisible: (list.length >= 15 ? true : false),
currentPage: 2
});
console.log(this.state.displayArray, 'dans initListData')
}
};
setNewData = async (page) => {
let list = await getProducts(parseInt(page));
if (list) {
this.setState({
displayArray: this.state.displayArray.concat(list),
loadMoreVisible: (list.length >= 15 ? true : false),
loadMoreVisibleAtEnd: false,
currentPage: parseInt(page)+1
});
}
};
loadMore() {
this.setNewData(this.state.currentPage);
}
displayBtnLoadMore() {
this.setState({
loadMoreVisibleAtEnd: true
});
}
async UNSAFE_componentWillMount() {
this.initListData();
console.log(this.state.displayArray, 'dans componentWillMount')
}
render() {
console.log('displayArray', this.state.displayArray)
return (
<View style={{flex: 1}}>
<Text>{"\n"}</Text>
<Text>{"\n"}</Text>
{this.state.displayArray !== null && this.state.displayArray.length > 0 ? (
<View style={{ flex: 1, marginBottom: 100 }}>
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.displayArray}
//extraData={this.selectedId}
//onEndReached={() => this.displayBtnLoadMore()}
renderItem={({item})=>
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('ProductDetails', {productId: parseInt(item.id)})}
/>
</View>
}
keyExtractor={item => "product-" + item.id.toString()}
style={{width:"90%"}}
/>
{this.state.loadMoreVisible === true && this.state.loadMoreVisibleAtEnd === true ? (
<Button title=" + " onPress={()=>{this.loadMore()}}></Button>
) : null
}
<View style={styles.container}>
<Text>{"\n"}</Text>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.container}>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
</TouchableOpacity>
</View>
<Text>{"\n\n"}</Text>
</SafeAreaView>
</View>
) : (
<View style={styles.container}>
<Text>{"\n\n" + (this.state.displayArray === null ? i18n.t("products.searching") : i18n.t("products.nodata")) + "\n\n\n"}</Text>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
)}
</View>
);
};
}
I have something like this:
const BasketButton2 = ({ isWhite, style, navigation }) => (
<TouchableOpacity
style={[styles.button, style]}
onPress={() => Header.addInstaPost()}
>
<Icon
family="Entypo"
size={16}
name="new-message"
color={theme.COLORS[isWhite ? 'WHITE' : 'ICON']}
/>
</TouchableOpacity>
);
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
notifications: false,
loading: true,
error: null,
modalVisible: false,
modalThanksVisible: false,
reportSubmitted: false,
reportError: false,
};
}
handleLeftPress = () => {
const { back, navigation } = this.props;
return back ? navigation.goBack() : navigation.openDrawer();
};
renderRight = () => {
const { white, title, navigation, scene } = this.props;
if (global.loggedUser === true) {
return [
<BasketButton2
key="basket-search"
navigation={navigation}
isWhite={white}
/>,
<ChatButton
key="chat-search"
navigation={navigation}
isWhite={white}
/>,
];
} else {
return [
<BasketButton
key="basket-search"
navigation={navigation}
isWhite={white}
/>,
<ChatButton
key="chat-search"
navigation={navigation}
isWhite={white}
/>,
];
}
};
renderSearch = () => {
const { navigation } = this.props;
return (
<Input
right
color="black"
style={styles.search}
placeholder="What are you looking for?"
onFocus={() => navigation.navigate('Search')}
iconContent={
<Icon
size={16}
color={theme.COLORS.MUTED}
name="magnifying-glass"
family="entypo"
/>
}
/>
);
};
renderOptions = () => {
const { navigation, optionLeft, optionRight } = this.props;
return (
<Block row style={styles.tabs}>
<Button
shadowless
style={[styles.tab, styles.divider]}
onPress={() => navigation.navigate('Categories')}
>
<Block row middle>
<Icon name="globe" family="feather" style={{ paddingRight: 8 }} />
<Text size={16} style={styles.tabTitle}>
{optionLeft || 'Locations'}
</Text>
</Block>
</Button>
<Button
shadowless
style={styles.tab}
onPress={() => navigation.navigate('Deals')}
>
<Block row middle>
<Icon name="grid" family="feather" style={{ paddingRight: 8 }} />
<Text size={16} style={styles.tabTitle}>
{optionRight || 'Categories'}
</Text>
</Block>
</Button>
</Block>
);
};
renderTabs = () => {
const { tabs, tabIndex, navigation } = this.props;
const defaultTab = tabs && tabs[0] && tabs[0].id;
if (!tabs) return null;
return (
<Tabs
data={tabs || []}
initialIndex={tabIndex || defaultTab}
onChange={(id) => navigation.setParams({ tabId: id })}
/>
);
};
renderHeader = () => {
const { search, tabs, options } = this.props;
if (search || tabs || options) {
return (
<Block center>
{search ? this.renderSearch() : null}
{options ? this.renderOptions() : null}
{tabs ? this.renderTabs() : null}
</Block>
);
}
return null;
};
addInstaPost = () => {
this.setState({ modalVisible: true });
};
render() {
const { back, title, white, transparent, navigation, scene } = this.props;
const noShadow = ['Profile'].includes(title);
const noShadowWhite = ['Search'].includes(title);
const headerStyles = [
!noShadow ? styles.shadow : null,
transparent ? { backgroundColor: 'rgba(0,0,0,0)' } : null,
];
var myHeaderStyle = styles.shadow;
if (noShadow) {
var myHeaderStyle = '';
} else if (transparent) {
var myHeaderStyle = "{ backgroundColor: 'rgba(0,0,0,0)' }";
} else if (noShadowWhite) {
var myHeaderStyle = styles.searchShadow;
}
return (
<Block style={myHeaderStyle}>
<View style={styles.imageContainer} transparent={transparent}>
{
this.renderInstaPostButton()
}
</View>
<View style={styles.item}>
<NavBar
back={back}
title={title}
style={styles.navbar}
transparent={transparent}
right={this.renderRight()}
rightStyle={{ alignItems: 'center' }}
leftStyle={{ paddingTop: 3, flex: 0.3 }}
leftIconName={back ? 'leftcircle' : 'menu-fold'}
leftIconFamily="AntDesign"
leftIconSize="1.6"
leftIconColor={
white ? materialTheme.COLORS.NAVICON : theme.COLORS.ICON
}
titleStyle={[
styles.title,
{ color: theme.COLORS[white ? 'WHITE' : 'ICON'] },
]}
onLeftPress={this.handleLeftPress}
/>
</View>
{this.renderHeader()}
</Block>
);
}
}
So basically inside BasketButton2 I am trying to make a call to a function which is inside the class Header.
onPress={() => Header.addInstaPost() is not working
as well as onPress={() => this.addInstaPost()
I am getting Header.addInstaPost is not defined.
How I can refer to function inside class?
Thanks!!
You can pass addInstaPost as a property to BasketButton2
class Header extends React.Component {
addInstaPost = () => {
this.setState({ modalVisible: true });
};
renderRight = () => {
const { white, title, navigation, scene } = this.props;
if (global.loggedUser === true) {
return [
<BasketButton2
key="basket-search"
navigation={navigation}
isWhite={white}
onPress={this.addInstaPost}
/>,
<ChatButton
key="chat-search"
navigation={navigation}
isWhite={white}
/>,
];
} else {
return [
<BasketButton
key="basket-search"
navigation={navigation}
isWhite={white}
/>,
<ChatButton
key="chat-search"
navigation={navigation}
isWhite={white}
/>,
];
}
};
}
const BasketButton2 = ({ isWhite, style, navigation, onPress }) => (
<TouchableOpacity
style={[styles.button, style]}
onPress={onPress}
>
<Icon
family="Entypo"
size={16}
name="new-message"
color={theme.COLORS[isWhite ? 'WHITE' : 'ICON']}
/>
</TouchableOpacity>
);
IMO this is the most prefered way for such case
I want to delete item from the FlatList. However, the solution from here is not working for my code. When I run my code, I am getting error such as 'index is not defined'.
I have yet to find other post regarding this issue so any help would be greatly appreciated.
Code snippet provided below:
export default class FrCreateScreen extends Component {
constructor(props) {
super(props);
this.state = {
//new timeSlots
timeSlots: [],
}
}
setEndTime = (event, appointmentEndTime, textEndTime) => {
appointmentEndTime = appointmentEndTime || this.state.appointmentEndTime;
textEndTime = textEndTime || moment(appointmentEndTime).format('h:mm a').toString();
this.setState({
showEndTime: Platform.OS === 'ios' ? true : false,
appointmentEndTime,
textEndTime,
timeSlots: [
...this.state.timeSlots,
{
apptdate: this.state.textAppointmentDate,
appttime: this.state.textAppointmentTime,
endTime: textEndTime,
}
],
});
}
deleteDateTime = (id) => {
const filteredData = this.state.timeSlots.filter(item => item.id !== id);
this.setState({ timeSlots: filteredData });
}
render() {
return (
<ScrollView>
...
<View>
<FlatList
data={this.state.timeSlots}
keyExtractor={({ id }, index) => index.toString()}
renderItem={({ item }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
/>
</View>
</ScrollView>
)
};
};
Screenshot below:
I think you need to add index inside renderItem { item, index }
renderItem = {({ item, index }) => {
return (
<View style={styles.containerList}>
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
);
}}
While rendering in map function , it provides the index too, so try adding that.
renderItem={({ item,index }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
Hope it helps
ok fixed. on touchable onPress, the argument should be 'item.index' instead of 'index'.
here's the correct code:
renderItem={({ item,index }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(item.index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
I have checkboxes inside Flatlist like this
constructor(props) {
super(props);
this.state = {
checked: false
}
}
breakfastData = ({item}) => {
return(
<ListItem style={{flex:1 , flexDirection: 'row' , justifyContent:'space-between'}} >
<Text>{item}</Text>
<CheckBox
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})} style={{ alignSelf: 'flex-end'}} color="#FC7B04" />
</ListItem>
)
}
render(){
return(
<View>
<FlatList
data={this.state.breakfast}
renderItem={ this.breakfastData }
keyExtractor={(item, index) => index}
/>
</View>
)
}
here is a screenshot from the app but the checkboxes don't work when i click any of the check boxes
i just want the user feel that the check box is checked
You must set checked for each item.
constructor(props) {
super(props);
this.state = {
breakfast:[
{id:1,checked:false},
{id:2,checked:false}
]
}
}
onItemPress = (item, index) => {
var tempItem = item
tempItem.checked = !item.checked
const tempArr = [...this.state.breakfast]
tempArr[index] = tempItem
this.setState({
breakfast: tempArr
})
}
breakfastData = ({item}) => {
return(
<ListItem style={{flex:1 , flexDirection: 'row' , justifyContent:'space-between'}} >
<Text>{item}</Text>
<TouchableOpacity onPress={() => {this.onItemPress(item,index)}}>
<CheckBox checked={item.checked} style={{ alignSelf: 'flex-end'}} color="#FC7B04" />
</TouchableOpacity>
</ListItem>
)
}
render(){
return(
<View>
<FlatList
data={this.state.breakfast}
renderItem={ this.breakfastData }
extraData ={ this.state}
keyExtractor={(item, index) => index}
/>
</View>
)
}
I have a Parent Class and Child Class but however i can't call a function on Parent Class from Child Class
It just for close the Modal and send a few data from Sorting on my modal. Sorry im a newbie on RN
On OrderScreen i want to separate a modal and screen, so i call modal on another file JS, then on ModalSort.js i want to call back that function has been on his Parents or Order.screen.js
so many way i try but that modal still can't close, if i put onBackdropPress={() => ()} the modal can be close but no respon that i got
Order.screen.js (a.k.a Parents.js)
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
};
exit = () => this.setState({ visibleModal: false });
_applySort = () => {
this.setState({ visibleModal: false });
this.onRefresh();
};
pressSort = () => this.setState({ visibleModal: 4 });
render() {
return (
<View style={styles.containerTop}>
<Modal isVisible={this.state.visibleModal === 5} style={styles.bottomModal}>
{this._renderModal()}
</Modal>
<Modal isVisible={this.state.visibleModal === 4}
style={styles.bottomModal} onBackdropPress={() => {this.toggleModal();}}>
{this._renderModalSort()}
</Modal>
<Modal isVisible={this.state.visibleModal === 3} style={styles.bottomModal}>
{this._renderModalFilter()}
</Modal>
<Modal isVisible={this.state.visibleModal === 2} style={styles.bottomModal}>
{this._renderModalEmail()}
</Modal>
<NavigationEvents
onWillFocus={this.willFocusAction} />
<GeneralStatusBarColor backgroundColor="#FFF" barStyle="light-content" />
</View>
)
};
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit.bind(this);
}}
/>
)
};
const mapStateToProps = ({ authOrder }) => {
const { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext } = authOrder;
return { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext };
};
export default connect(mapStateToProps, { getOrderSummary, getOpenOrderList, getClosedOrderList, sendEmailCsvAllOrder, logoutSession })(OrderScreen);
ModalSort.js (a.k.a Child.js)
class ModalSort extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
}
};
sorter = (isi) => this.setState({ sorted: isi });
_applySort = () => {
this.setState({ visibleModal: false });
// this.onRefresh();
};
render() {
return(
<View style={styles.modalContentSort}>
<View style={styles.modalCenter}>
<View style={styles.headerModel}>
<View style={styles.headerBack}>
<TouchableOpacity onPress={()=>{this.props.exit()}}>
{/* <NavigationEvents onWillFocus={this.willFocusAction} /> */}
<Image style={styles.logoClose} source={require('../../assets/icons/iconClose.png')} />
</TouchableOpacity>
</View>
<View style={styles.headerSort}>
<Text style={styles.textFilter}>Sort by</Text>
</View>
</View>
<Text style={styles.textFilter}>SO Number</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(1)}>
<Text style={this.state.sorted == 1 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(2)}>
<Text style={this.state.sorted == 2 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>PO Customer</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(3)}>
<Text style={this.state.sorted == 3 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(4)}>
<Text style={this.state.sorted == 4 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>SO Date</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(6)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 6 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(5)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 5 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<Text style={styles.textFilter}>ETA</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(8)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 8 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(7)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 7 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<TouchableHighlight style={styles.buttonSort} onPress={this._applySort.bind(this)} >
<Text style={styles.textApply}>Apply</Text>
</TouchableHighlight>
</View>
</View>
)
};
}
export default ModalSort;
Close modal in Parent component from Child component:
Your Order.screen.js has a mistake that make your program wouldn't run properly. When you use this.exit.bind(this);, it will return a callback, not a function. So, when you call this.props.exit() in ModalSort.js, it will call exit that actually shows nothing. To resolve this, you have 2 ways:
Order.screen.js
_renderModalSort = () => {
return (
<ModalSort
exit={this.exit.bind(this)}
/>
)
};
or
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
/>
)
};
Send data from sorting modal:
Since you're using Redux, I suggest you create 2 actions. First action is to save your data to your state tree. Second one is to get those data. If you're not good at Redux, or you don't want to use it, you can try these step:
Initialize a variable to hold your data in Parent:
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
this.data = null; // Your data goes here.
/*
You can store your data in state if you want to re-render when updating your data.
this.state = {
visibleModal: null,
data: null
}
*/
}
}
Create a function that save your data in Parent:
saveData(data) {
this.data = data;
}
Pass that function to Child:
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
saveData={(data) => {
this.saveData(data);
}}
/>
)
};
Lastly, you can call it from Child:
class ModalSort extends Component {
sorting() {
data = null; // Your data will be stored in this variable
// You sorting function goes here
this.props.saveData(data); // Save your data
}
}
In case you have other works to do with saved data, you can modify the saveData(data) function in Parent.
Hope this will help you!