I'm trying to pass some data from container to modal, and i've done this. it got error undefined is not an object evaluating (evaluating _this.props.status) is there anything i did worng? what should i call in props
these are my codes
container.js
buildPanel(index, item) {
let panel = [];
let keys = DBkeys['Requests'].MyRequest;
let status = item[keys['status']];
panel.push(<View style={{ position: 'absolute', right: 0, bottom: 0, padding: normalize(5), alignItems: 'center' }} key={'status'}>
<TouchableOpacity onPress={this.handleShowModal()}>
<Icon name={img.itemStatus[status].name} type={img.itemStatus[status].type} color={img.itemStatus[status].color} size={normalize(38)} />
</TouchableOpacity>
</View>);
return panel;
}
<View style={[styles.panelContainer, status === 'success' ? {} : { backgroundColor: color.white }]}>
<FlatList
showsVerticalScrollIndicator={false}
progressViewOffset={-10}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
onMomentumScrollEnd={(event) => event.nativeEvent.contentOffset.y === 0 ? this.onRefresh() : null}
data={content}
renderItem={({ item }) => item}
keyExtractor={(item, key) => key.toString()}
/>
</View>
<IconModal visible={this.state.modalVisible} close={this.handleDismissModal} status='test' desc='test' />
IconModal.js
const IconModal = (props) => {
return(
<Modal
isVisible={props.visible}
onBackdropPress={props.close}
>
<View style={styles.dialogBox}>
<View style={styles.icon}>
<Icon></Icon>
</View>
<View style={styles.text}>
<Text style={styles.status}>{this.props.status}</Text>
<Text>{this.props.desc}</Text>
</View>
<TouchableOpacity onPress={props.close}>
<View>
<Text style={styles.buttonText}>GOT IT</Text>
</View>
</TouchableOpacity>
</View>
</Modal>
)
}
IconModal.propTypes ={
visible: PropTypes.bool.isRequired,
close: PropTypes.func,
}
Use double quotes while passing string to the component. like status="test" desc="test" instead of status='test' desc='test' . and instead of this.props.status use props.status. same with this.props.desc
Remove the this keyword. It should be just props.status and props.desc
Related
Good evening everyone .
I have created the following Flatlist :
<View style={{ flex: 1 }}>
<FlatList
ListFooterComponent={
loadMore && page < pageMax ? (
<ActivityIndicator color={Colors.grey40} />
) : (
<View />
)
}
ListFooterComponentStyle={{ height: 200 }}
contentContainerStyle={styles.listExercise}
keyExtractor={() => uuid.v4()}
data={exercises}
renderItem={renderItemRE}
removeClippedSubviews={true}
onEndReached={() => {
setOnEndReachedCalledDuringMomentum(true);
}}
onMomentumScrollEnd={loadMoreFc}
onEndReachedThreshold={0.3}
ListEmptyComponent={
<Text contentW B18>
Nessuna Esercizio presente
</Text>
}
/>
</View>
This is renderItem function
const renderItemRE = ({ item }) => {
return (
<RenderItemRE
selectables={route.params?.selectables}
item={item}
navigation={navigation}
/>
);
};
And finally this is my component RenderItemRE
const RenderItemRE = ({ item, navigation, selectables }) => {
return (
<View style={styles.globalContainer}>
<TouchableOpacity
style={styles.touchable}
onPress={() => {
navigation.navigate(Routes.InfoEsercizio, {
id_ex: item.id,
nomeEx: item.nome,
});
}}
>
<View style={styles.container}>
<Image
indicator={Progress}
style={styles.img}
source={{
uri: item.galleria
? item.galleria[0]
? item.galleria[0]
: "logo"
: ApiConstants.DEFAULT_IMAGE,
}}
/>
<Text
style={[
customtext(DYNAMIC_FONTS_SIZE.FONT_SIZE_BIG).regular,
styles.nameStyle,
]}
>
{item.nome}
</Text>
</View>
</TouchableOpacity>
</View>
);
};
function arePropsEqual(prevProps, nextProps) {
return nextProps.item.id === prevProps.item.id;
}
export default memo(RenderItemRE, arePropsEqual);
This is a correct way to use memo in react native ? Or am I doing something wrong? I'm noticing that when the list gets bigger the rendering slows down. I was wondering what was the correct way to optimize. Thank you in advance
I am rendering separate cards in my render function by using data from an array. However I want a button within each Card to be pressed and only affect that exact Card.
this.state = {
isLiked: false,
feed: [{
username: ["stuff","here"],
caption: ["more","stuff"]
}]
}
toggleLike = () => {
this.setState({
isLiked = !this.state.isLiked
})
}
renderFeed = () => {
return this.state.feed.map((card, index) => {
return card.username.map((username, i) => {
if(card.caption[i])
return (
<View>
<TouchableHighlight
onPress={()=>this.toggleModal({caption:card.caption[i],username:card.username[i]})}
underlayColor="white">
<Card
key={`${i}_${index}`}
containerStyle={{borderRadius:10, marginRight:1, marginLeft:1,}}>
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ flexDirection: 'row'}}>
</View>
<View style={{flexDirection:'row'}}>
{this.state.isLiked ?(
<Avatar rounded icon={{name: 'heart-multiple-outline', type: 'material-community'}} overlayContainerStyle={{backgroundColor: '#ff4284',marginLeft: 5}} reverse size="small" onPress={()=> this.toggleLike()}/>
) : (
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community', color: '#ff4284'}}
overlayContainerStyle={{marginLeft:5}}
reverse
size='small'
onPress={()=> this.toggleLike()}/>
)}
</View>
</View>
<View style={{flexDirection:'row'}}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}} key={username}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}} key={card.caption}>{card.caption[i]}</Text>
</Card>
</TouchableHighlight>
</View>
);
return <React.Fragment />;
});
})
}
render(){
{this.renderFeed()}
}
Is there any way I can make it so that each card's like button is independent?
Here is an expo snack so you can see what I mean. https://snack.expo.io/#sooper_fly/demoforlikes
I build expo snack, Something like this:
https://snack.expo.io/#djalik/demoforlikes
you can improve your code and make card/item component and set the data over props.
Recommend: Work with FlatList
I am new to react native development. In my application I need to change the color of the view based on the condition. So my question is can I use if condition between the views in react native. The following is the code
import React, {Component} from 'react';
import {StyleSheet, FlatList, Text, View, Alert,Image,TouchableOpacity} from 'react-native';
export default class Myproject extends Component {
constructor(props)
{
super(props);
this.state = { FlatListItems: [
{key: 'One'},
{key: 'Two'},
{key: 'Three'},
{key: 'Four'},
{key: 'Five'},
{key: 'Six'},
{key: 'Seven'},
{key: 'Eight'},
{key: 'Nine'},
{key: 'Ten'},
{key: 'Eleven'},
{key: 'Twelve'}
]}
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
marginLeft: 12,
backgroundColor: "#607D8B",
}}
/>
);
}
GetItem (item) {
Alert.alert(item);
}
render() {
return (
<View style={styles.MainContainer}>
<FlatList
data={this.state.FlatListItems}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={
({item}) =>
<View style={styles.mainItem}>
<View style={styles.itemContainer}>
<View>
<Image source={require('./resource/ic_drawer.png')} />
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)}>{item.key}</Text>
</View>
<View style={styles.balanceItem}>
<View>
<Text >Balance</Text>
<Text style={{color: '#000',fontSize: 18}}>$89.04</Text>
</View>
<View style={styles.subItem}>
<View>
<Text >Account number</Text>
<Text style={{color: '#000',fontSize: 14}}>743509-001</Text>
</View>
<View style={styles.balanceItem}>
<Text >Meter number</Text>
<Text style={{color: '#000',fontSize: 14}}>17976849</Text>
</View>
</View>
</View>
<View style={styles.balanceItem}>
<View style={styles.duenbuttonItem}>
<View>
<Text >Due Date</Text>
<Text style={{color: '#000',fontSize: 14}}>30/09/2016</Text>
</View>
</View>
<TouchableOpacity style={styles.btn} onPress={this.login}><Text style={{color: 'white',fontSize: 14}}>PAY NOW</Text></TouchableOpacity>
</View>
<Image source={require('./resource/arrow_24.png')} style={styles.arrowImage}/>
</View>
</View>
}
/>
</View>
);
}
login=()=>{
alert("testing......");
// this.props.navigation.navigate('Profile');
}
}
I want the output like the below image
I have designed everything fine. But the problem is green arrow and white arrow. I have designed these arrows too. But these arrows are displaying based on the condition.
I have tried like this but getting the following issue
if(item.key == "One"){
<View style={{borderColor: 'black',borderWidth: 6,marginBottom: -6}}/>
}else{
<View style={{borderColor: 'white',borderWidth: 6,marginBottom: -6}}/>
}
So here the problem is string comparison or any other problem.
You can do even better than returning a new view. In your case you only want to change the bg color, so you can have a ternary condition inside your style like this:
<View style={{borderColor: item.key == "One" ? "black" : "white"}}/>
UPDATE for multiple condition :
defineBgColor(key){
switch(key){
case "One":
return "black";
case "Two":
return "white";
case "Three":
return "orange";
}
}
render(){
<View style={{borderColor: this.defineBgColor(item.key)}}/>
}
An 'if' condition is a statement (doesn't have a return value).
Use ternary operator you'll have a return value.
{item.key == "One" ?
<View style={{borderColor: 'black',borderWidth: 6,marginBottom: -6}} /> :
<View style={{borderColor: 'white',borderWidth: 6,marginBottom: -6}} /> }
This may work.
{item.key == "One" ?
<View style={{borderColor: 'black',borderWidth: 6,marginBottom: -6}} /> :
<View style={{borderColor: 'white',borderWidth: 6,marginBottom: -6}} />}
However, if the only thing that differs is the borderColour, you could use something like
<View style={item.key == "One" ? styles.blackborder : styles.whiteborder} />
with blackborder and white border defined
blackborder {
...
}
whiteborder {
...
}
const getBorderColor = key => {
const searchKey = key.toLowerCase();
const borderMap = {
one: 'green',
two: 'red',
three: 'white',
};
return borderMap[searchKey];
};
<FlatList
data={this.state.FlatListItems}
renderItem={({item}) => <View style={{borderColor: this.getBorderColor(item.key)}} />}
/>
I have a rendered list and I would like it when a change in status is generated the entire FlatList is recharged
what I have is a search engine and I want that when it brings the new data the FlatList will refresh itself with the new information
I need that every time you enter a letter in the search engine the FlatList will recharge
async buscar(buscar) {
this.setState({refreshing: true});
const coins = await ajax.searchProd(buscar);
this.setState({coins});
console.log(coins);
this.setState({refreshing: false});
}
render() {
return (
<View style={styles.container}>
<Image style={styles.logoHeader} source={require('../../public/images/productos.png')}/>
<View style={styles.containerSearch}>
<TextInput
style={styles.inputBuscar}
placeholder={'Buscar Productos'}
underlineColorAndroid={"transparent"}
onChangeText={(buscar) => {
this.setState({buscar: buscar});
this.buscar(this.state.buscar);
console.log(this.state.buscar);
}}
/>
<Image style={styles.imageSearch} source={require('../../public/images/search.png')}/>
</View>
<View style={styles.containerPro}>
<FlatList
extraData={this.state.coins}
data={this.state.coins}
keyExtractor={(item) => item.id.toString()}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
/>
}
renderItem={({item}) => {
let url = 'http://laeconomiadelsur.com/upload/' + item.foto;
const tableData = [
[<View>
<Image source={{uri: url}} style={{
width: 50,
height: 70,
}}/>
</View>,
],
[<View style={styles.cellIcons}>
<Text
style={styles.textCells}>{item.nombre}</Text>
<Text
style={styles.textCellsDescription}>{item.descripcion}</Text>
<Text
style={styles.textCellsPrecio}>{numeral(item.precio).format('$0,0')}</Text>
</View>,
],
[<View>
<Text style={styles.cantidad1}>seleccionar: </Text>
<View>
<NumericInput
onChange={(value) => {
let total = value * item.precio;
console.log(value);
console.log(total)
}}
totalWidth={calcSize(250)}
totalHeight={calcSize(70)}
minValue={0}
iconSize={15}
step={1}
sepratorWidth={0}
borderColor={'transparent'}
inputStyle={{
backgroundColor: 'rgb(252,226,227)',
borderTopColor: 'rgb(226,0,30)',
borderBottomColor: 'rgb(226,0,30)',
borderWidth: 1,
fontFamily: "NeutraText-BookSC",
fontSize: 17
}}
containerStyle={{
borderWidth: 1,
borderColor: 'rgb(226,0,30)',
backgroundColor: 'transparent',
}}
rounded
textColor='#000000'
rightButtonBackgroundColor={'rgb(235,209,210)'}
leftButtonBackgroundColor={'rgb(235,209,210)'}
/>
</View>
<Text style={styles.cantidad}>cantidad</Text>
</View>,]
];
return (
<View style={{flex: 1}} key={item.id}>
<Table style={styles.table} borderStyle={{borderWidth: 2, borderColor: 'white'}}
key={item.id}>
<Cols data={tableData} flexArr={[1, 2, 2]} style={styles.cells}
key={item.id}/>
</Table>
</View>
);
}}
/>
</View>
</View>
);
<TextInput
style={styles.inputBuscar}
placeholder={'Buscar Productos'}
underlineColorAndroid={"transparent"}
onChangeText={(buscar) => {
/* Updated buscar value won't be available in next line instantly
* just after the setState. So, better set buscar State in
* this.buscar() Function.
*/
/* this.setState({buscar: buscar}); Move to buscar Function*/
this.buscar(buscar).then(()=>{
console.log(this.state.buscar);
}).catch((e)=> console.log("Error: ",e))
}}
/>
An Async function always returns a promise object. So, while calling buscar function you should handle the promise.
async buscar(buscar) {
this.setState({
refreshing: true,
buscar: buscar,
});
const coins = await ajax.searchProd(buscar);
console.log(coins);
this.setState({
coins: conins,
refreshing: false
});
}
In Flatlist ExtraData property should contain the this.state
extraData={this.state}
I've got a SectionList, and for every row in the list I want to be able to detect a click event.
renderList() {
if (this.state.searching) {
return (
<SectionList
sections={this.state.data}
renderSectionHeader={this.props.renderSectionHeader}
renderItem={this.props.renderItem}
/>
);
}
return null;
}
render() {
return (
<View style={styles.container}>
<Animated.View
style={{ opacity: 1 - this.state.backgroundColor }}
pointerEvents={this.state.searching ? 'none' : undefined}
>
{this.props.children}
</Animated.View>
<Animated.View
style={[
styles.backgroundColorView,
{ opacity: this.state.backgroundColor },
]}
/>
<Animated.View
style={[styles.searchResults, { top: this.state.yPos }]}
>
<TextInput
ref={(input) => { this.searchBar = input; }}
style={styles.textInput}
value={this.props.query}
onChangeText={this.onChangeText}
maxLength={100}
placeholder={this.props.placeholder}
onFocus={this.onFocus}
onBlur={this.onUnSearch}
/>
{this.renderList()}
</Animated.View>
</View>
);
For my renderItem method, I'm passing in the following PureComponent, which is just a Text contained in a TouchableHighlight.
class SubjectSearchItem extends React.PureComponent {
render() {
const item = this.props.item;
return (
<TouchableHighlight
onPress={() => console.log(item)}
>
<View style={{
marginHorizontal: 20,
marginVertical: 10,
}}
>
<Text>{`${item.item.long_name} (${item.item.short_name})`}</Text>
</View>
</TouchableHighlight>
);
}
}
and here's the renderItem prop I'm passing in
const renderItem = item => (
<SubjectSearchItem
item={item}
/>
);
The problem is, no click events are being detected. The row isn't getting highlighted, and the onPress isn't being fired. Any ideas?
Note: seems like this has been an issue for a little while