Styling array mapped objects in React Native - javascript

return arr.map((entry, index) =>
<View style={ this.state.interests.includes(entry) ? styles.optionSelected : styles.option}>
<TouchableOpacity onPress={() => this.addToInt(entry)}>
<Text style={{ color: "#22305D", paddingVertical: 15, paddingHorizontal: 25, fontSize: 18 }} key={entry}>{`${entry}`}</Text>
</TouchableOpacity>
</View>
)
I currently have this code to traverse my array and display all the values, but I want a way to change the styling of an individual object when pressed. The way I have it now, onPress adds that unique value to the array interests (100% sure this works), but the conditional styling isn't working. Is there a different way of handling this? I am trying to avoid setting a state for option1, option2, etc.. Thanks!

Related

Get the key value when i click the respective TouchableOpacity from mapping an array

Im new to react native and im doing an internship but noone can really help me and i've been stuck with this for a while, my question is, im mapping an array that will basicly list news from an api each in a rectangle with title, subject and date. Everything is working but i wanted to click a rectangle for example so it shows more of that specific new but i dont know if there is any way i can store the key value in a variable so i can get the right coordinates of the array
{this.state.noticias.map((noticias, i) => (
(this.state.noticias[i][0] && this.state.noticias[i][1] && this.state.noticias[i][2]) == "" ?
<View key={i}></View> :
<TouchableOpacity style={styles.noticiaContainer} key={i}
onPress={this.mostrarNoticia.bind(this)} >
<View style={{ borderBottomWidth: 1, borderColor: '#0e62a5', }}>
<Text style={styles.tituloNoticia}>{noticias[0]}</Text>
</View>
<Text style={styles.assuntoNoticia}>{noticias[1]}</Text>
<Text style={styles.dataNoticia}>{noticias[2]}</Text>
</TouchableOpacity>
))}
The second argument to bind is the set of arguments to pass into the new function, so in your code where you're mapping each of your 'noticias', you're creating a new function with bind, and passing in the current 'this' value as the first parameter, but not passing in any variables.
Observe the amendment I have made to your code below, I have passed in both the 'noticias' and 'i' values as the 2nd & 3rd parameters to the bind function call.
{this.state.noticias.map((noticias, i) => (
(this.state.noticias[i][0] && this.state.noticias[i][1] && this.state.noticias[i][2]) == "" ?
<View key={i}></View> :
<TouchableOpacity
style={styles.noticiaContainer}
key={i}
onPress={this.mostrarNoticia.bind(this, noticias, i)} >
<View style={{ borderBottomWidth: 1, borderColor: '#0e62a5', }}>
<Text style={styles.tituloNoticia}>{noticias[0]}</Text>
</View>
<Text style={styles.assuntoNoticia}>{noticias[1]}</Text>
<Text style={styles.dataNoticia}>{noticias[2]}</Text>
</TouchableOpacity>
))}
Taking the above modification I've stubbed out an example function signature for 'mostrarNoticia', along with the fix for bind should look something like below.
import React from "react";
class YourComponent extends React.Component {
mostrarNoticia (noticias, index) {
// Given you passed the values into the bind function,
// they will be accessible here.
console.log("noticias", noticias);
console.log("index", index);
}
render () {
return (
<>
{this.state.noticias.map((noticias, i) => (
(this.state.noticias[i][0] && this.state.noticias[i][1] && this.state.noticias[i][2]) == "" ?
<View key={i}></View> :
<TouchableOpacity
style={styles.noticiaContainer}
key={i}
onPress={this.mostrarNoticia.bind(this, noticias, i)} >
<View style={{ borderBottomWidth: 1, borderColor: '#0e62a5', }}>
<Text style={styles.tituloNoticia}>{noticias[0]}</Text>
</View>
<Text style={styles.assuntoNoticia}>{noticias[1]}</Text>
<Text style={styles.dataNoticia}>{noticias[2]}</Text>
</TouchableOpacity>
))}
</>
);
}
}
Basically, pass the variables into the function using the bind function you're already using.

React native - Change styles dynamically

I have a dynamic menu that I created using a map method.
{navigationOptions.map(option => {
return (
<TouchableOpacity key={option.code}
onPress={() => this.procedureOptionSelected(option.code)}
>
<Text bold style={header.NavigationBarOption}>
{option.type}
</Text>
</TouchableOpacity>
);
})}
However, I need an underline when I press a menu option.
So let's assume, that I pressed the first option. So, in the first option, there must be an underscore.
But I don't know how to do this in react native.
Could someone help me with an idea?
Thanks!
You can add a style prop to TouchableOpacity and check if this is the selected button like this:
<TouchableOpacity
style={{ borderBottomWidth: this.state.selected === option.code ? 1 : 0 }}
onPress={() => this.setState({ selected: option.code })
>
...
</TouchableOpacity>
Also I guess you can use this.procedureOptionSelected() since you set that option.code in there too!

is there way to return Text and View together ? because it doesn't work for me

This is my example of return jsx elements inside the loadingMessage.
return (
<AzureLoginView
azureInstance={this.azureInstance}
loadingMessage={
<Text style={{ fontSize: 20, fontWeight: "bold" }}>loding data</Text>
Here it doesn't let me put my view inside the loadingMessage as listed below and I don't understand why.
<View style={styles.appBottomMainContainer}>
<View style={styles.appBottomView}>
<Text>{'\u00A9'}Developed by Mobile Team</Text>
</View>
</View>
}
onSuccess={this._onLoginSuccess}
/>)
As per the docs it states AzureLoginView loadingMessage should be a string rather than a JSX component. So try instead with that.
But in future , for any other components , yes you can return JSX components like FlatList uses it, Like thr one in renderItem :
<FlatList
data={this.props.tripsReducer.trips}
renderItem={({item, index}) => {
return (<View><Text>{item}</Text></View>);
}}
/>

How to render Container Classes conditionally

firstly, this is what is given to me from designer http://www.giphy.com/gifs/hSRrqF5ObsbXH27V09
Basically, there is a category which is passed from previous screen. and with some ui interactions, i need to render this screen again and again. the flow is like that: you select a category, if it has subCategories, let user select one of those subCategories before rendering input components. i can make it work with if and else clauses but i feel that this is some how not best practice at all. I just need an advice from experieced developer(i am reletively new to react native.)
So before writing any code with native way, i just want to ask it here so maybe i can learn more about it.
Here is my Screen:
<NewAdHoc
contentText={'Kategori Secimi'}
onBackPress={this.handleBackPress}
showContentText={false}
>
<View style={styles.container}>
{currentCategory !== null
? (
<View style={{ ...styles.flatListContainer, paddingLeft: undefined, paddingRight: undefined }}>
<View style={{ marginHorizontal: 20 }}>
<ListViewItem
categoryName={currentCategory.categoryName}
iconName={currentCategory.categoryIcon}
showBorder={false}
key={currentCategory.categoryId}
categoryId={currentCategory.categoryId}
inNewAdScreen={false}
/>
</View>
<Seperator
backgroundColor={colors.SEPERATOR_BCK}
text={'Ilan Turu'}
style={{ paddingHorizontal: 20 }}
/>
{
currentCategory.subCategories.map((subc) => (
<View style={{ marginHorizontal: 20 }}>
<SubCategoryItem
text={subc.subCategoryName}
key={subc.subCategoryId}
showBorder={true}
/>
</View>
))
}
</View>
) : null}
</View>
</NewAdHoc>
right now, i am rendering a category, a <Seperator/> between category and subcategories, and subcategories. what i want is that, when user click on one of the subCategories, i will change the state to isSubCategorySelected = true, selectedSubCategory= subCategoryId and then need to render the whole screen like in gif i provided above.
the For those who came here for answer:
What i did is basically divide and conquer paradigm. I firstly divide my sitution into two main state.
RenderInitialForm(),
renderAfterSubCategorySelected(),
those two rendering functions handle the whole process. when a TouchableOpacity is clicked, i setState with two variables: isSubCategorySelected = true, selectedSubCategory = subCategory
and in my main render() function:
render() {
const { currentCategory, isSubCategorySelected, selectedSubCategory } = this.state
return (
<NewAdHoc
contentText={'Kategori Secimi'}
onBackPress={this.handleBackPress}
showContentText={false}
>
<View style={styles.container}>
{currentCategory !== null
? isSubCategorySelected
? this.renderAfterSubCategorySelected()
: this.renderInitialForm()
: null}
</View>
</NewAdHoc>
);
}
if you have any suggestion with my solution, please feel free to contact me.

Reactjs assigning key prop to array rendered components

I am rendering some components using array map function, and I'm getting "Each child in an array or iterator should have a unique "key" prop." warning. I know that I do have to assign key props to the array rendered components.
My question is, do I have to just assign key to the most outer component (this case View) that is inside the map function, or do I have to assign key to every element inside the outer most component view?
If latter is the case, then assigning key to every component is a little inefficient I think? Is there any way to solve this problem? Thank you
this.state.Store.City.map((item) => {
return <View>
<TouchableOpacity onPress={() => this.onQueryInputChange(item)}>
<Text style={{ fontSize: 20, paddingVertical: 10 }}>
{item.fullName}
</Text>
</TouchableOpacity>
</View>
})
If you don't have an id in item, you can use the item array index if the list will not be reordered or reorganized :
this.state.Store.City.map((item, index) => {
return (
<View key={index}>
<TouchableOpacity onPress={() => this.onQueryInputChange(item)}>
<Text style={{ fontSize: 20, paddingVertical: 10 }}>
{item.fullName}
</Text>
</TouchableOpacity>
</View>
);
})
Only the outermost component needs a key to keep track of each item.
You should assign a key to the most outter component (here it would be View component)
here is the documentation
if item has an ìd property you could write
this.state.Store.City.map((item) => {
return (
<View key={item.id}>
<TouchableOpacity onPress={() => this.onQueryInputChange(item)}>
<Text style={{ fontSize: 20, paddingVertical: 10 }}>
{item.fullName}
</Text>
</TouchableOpacity>
</View>
);
})

Categories

Resources