Function inside Flatlist RenderItem is not fully working - javascript

Problem is I cannot see {item.key} inside my function. When I type {item.key} itself inside flatlist render it is working. But inside function only {item.value} is showing. Can anyone explain to me why this happening ?
Sample Data
const orderResultJson = [
{
key: 'Скачайте приложение по ссылке',
value: 'https://google.com'
},
{
key: 'Логин',
value: '879854'
},
{
key: 'Пароль',
value: '849846'
},
];
My Function
function DetailsSection(item){
return(
<View>
<Text>{item.value}</Text>
<Text>{item.key}+test</Text>
</View>
)
}
Render
render() {
return (
<View style={styles.container}>
<FlatList
data={orderResultJson}
renderItem={({item}) => <DetailsSection {...item} />}
keyExtractor={item => item.key}
/>
</View>
);
}

Problem here is, when you are deconstructing item as individual props, the prop key will be considered as in built react prop key instead of considering it as an external prop.
So instead of deconstructing, pass item as is and access it from your function as it is.
My Function
function DetailsSection({ item }){
return(
<View>
<Text>{item.value}</Text>
<Text>{item.key}+test</Text>
</View>
)
}
Render
render() {
return (
<View style={styles.container}>
<FlatList
data={orderResultJson}
renderItem={({item}) => <DetailsSection item={item} />}
keyExtractor={item => item.key}
/>
</View>
);
}

function DetailsSection(props){
return(
<View>
<Text>{props.item.key} + test</Text>
<Text>{props.item.value}</Text>
</View>
)
}
Or
pass like this
<DetailsSection item={item} />
and access like this
function DetailsSection({ item }){
return(
<View>
<Text>{item.value}</Text>
<Text>{item.key}+test</Text>
</View>
)
}
because you are passing extracted value so directly you can access

Related

React Native Carousel UseState

I am currently implementing a carousel library (react-native-reanimated-carousel). The code for the following is represented as such:
<Carousel
width={cardWidth}
height={cardHeight}
data={cards}
onScrollEnd={() => {console.log('ended')}}
renderItem={({item}) =>
(
<View>
<Image
source={{uri: item["ImgURL"],}}
style={styles.card}
/>
</View>
)}
/>
Upon the carousel changing, the item value in the renderItem property changes. Is there a way to get the value of item from outside this element? I want other elements outside to change depending on the value (and properties) of item.
You could try to call a callback function in the renderItem function.
() => {
const [activeItem, setActiveItem] = useState(cards[0].item);
return (<Carousel
width={cardWidth}
height={cardHeight}
data={cards}
onScrollEnd={() => {console.log('ended')}}
renderItem={({item}) => {
setActiveItem(item);
return (
<View>
<Image
source={{uri: item["ImgURL"],}}
style={styles.card}
/>
</View>
);
}}
/>)
);
};
Or you could use onScrollEnd. It provides the previous index and the current index according to the documentation
() => {
const [activeItem, setActiveItem] = useState(cards[0].item);
return (<Carousel
width={cardWidth}
height={cardHeight}
data={cards}
onScrollEnd={(previous, current) => {
setActiveItem(cards[current].item);
console.log('ended')
}}
renderItem={({item}) => (
<View>
<Image
source={{uri: item["ImgURL"],}}
style={styles.card}
/>
</View>
)}
/>)
);
};
Or you could use the Ref prop getCurrentIndex

How can I display array elements passed as a prop to functional component?

I have created amenitiesArray which has elements like club_house, swimming_pool, etc. I am mapping over this amenitiesArray using .map() but when I pass it as a prop I am not able to display it on screen why so?
console.log(amenitiesArray) is:
0:"Gymnasium"
1:"swimming_pool"
2:"club_house"
3:"childrens_play_area"
4:"multipurpose_room"
5:"security"
6:"jogging_track"
7:"power_backup"
8:"landscaped_gardens"
9:"car_parking"
Code:
const DisplayAmenities = ({ name }) => (
<Text style={{ color: 'black', fontSize: 16 }}>{name}</Text>
);
export default class Project extends Component {
render() {
let amenitiesArray = [];
for (var key in amenities[0]) {
if (amenities[0][key] === 'Yes') {
amenitiesArray.push(key);
}
}
console.log(amenitiesArray);
return (
<ScrollView>
<View style={{ marginTop: 20 }}>
{amenitiesArray.map(val => {
<DisplayAmenities name={val} />;
})}
</View>
</ScrollView>
);
}
}
Above code does not display anything on screen? Why so?
Because you forgot to return the component. Try to fix like this:
return (
<ScrollView>
<View style={{ marginTop: 20 }}>
{amenitiesArray.map((val,index) => {
return <DisplayAmenities key={index} name={val} />; //fixed
})}
</View>
</ScrollView>
);
For short, you could omit the curly brackets, like so
return (
<ScrollView>
<View style={{ marginTop: 20 }}>
{amenitiesArray.map((val,index) => <DisplayAmenities key={index} name={val} /> )}
</View>
</ScrollView>
);
{amenitiesArray.map(val => {
<DisplayAmenities name={val} />;
})}
lacks explicit return, map callback function maps an array to an array of undefined.
For implicit arrow return, it should be:
{amenitiesArray.map(val =>
<DisplayAmenities name={val} />;
)}
The use of array-callback-return ESLint rule allows to avoid this sort of mistakes.

How do I navigate between List and Item?

I am trying to open an item from my list but my item code is in another js. When I try to use onPress method there is no action. Also I am using Swipeout.
Here is my JobList.js where I am rendering the list of my items.
class JobList extends Component {
onJobDetails = (job) => {
this.props.navigate('JobDetails', job);
}
render() {
const { navigation } = this.props;
var renderJobs = () => {
return this.props.jobs.map((job) => {
return (
<JobItem
key={job._id}
title={job.title}
shortDescription={job.shortDescription}
logo={job.avatar}
company={job.company}
id={job._id}
dispatch={this.props.dispatch}
onPress={() => this.onJobDetails(job)}
/>
)
})
}
return (
<View style={styles.container}>
<ScrollView>
{renderJobs()}
</ScrollView>
</View>
);
}
};
And here is my JobItem.js
class JobItem extends Component {
render() {
return (
<Swipeout {...swipeSettings}>
<View style={styles.jobContainer}>
<View>
<Text style={styles.postTitle}>{this.props.title}</Text>
<Text style={styles.postShortDescription}>{this.props.shortDescription}</Text>
</View>
<View>
<Image
style={styles.postLogo}
source={{uri: '' + this.props.logo + ''}}/>
</View>
</View>
</Swipeout>
)
}
};
Any idea how shall I fix this?
You need to pass onPress prop to the child component in order for it to work.
<Swipeout {...swipeSettings}>
<TouchableWithoutFeedback onPress={this.props.onPress}>
//... other children here
</TouchableWithoutFeedback>
</Swipeout>

How to use ReactNative FlatList ScrolltoIndex properly?

I'm a newbie in react native and I'm running into an issue I didn't manage to solve by myself.
So far this is how I am using it:
export default class Form extends React.Component {
state = {index: 0};
_keyExtractor = (item, index) => item.id;
myscrollToIndex = () => {
this.setState({index: ++this.state.index});
this.flatListRef.scrollToIndex({animated: true,index: this.state.index});
};
_renderItem = ({item}) => (
<View>
<Question {...item} />
<Button label='Next' onPress={this.myscrollToIndex} style={styles.buttonNext}/>
</View>
)
render() {
return (
<View style={styles.container}>
<FlatList
horizontal={false}
ref={(ref) => { this.flatListRef = ref; }}
scrollEnabled
data={this.props.form}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem} />
</View>
);
}
}
I would like to pass the index to myscrolltoindex function but I don't manage to as this.flatListRef gets ruled out when I do that.
Have anyone run into a similar issue ?
Thank you for your time
Use index param as well. And pass the index around.
For e.g _renderItem = ({item, index}) => ( <View> <Question {...item} /> <Button label='Next' onPress={this.myscrollToIndex(index) } style={styles.buttonNext}/> </View> )

React Native loop this

when I put onPress in a map loop, it doesn't work. how to fix it?
var PageOne = React.createClass({
_handlePress() {
this.props.navigator.push({id: 2,});
},
render () {
return (
<View>
<TouchableOpacity onPress={this._handlePress}> //work here
<Text> One </Text>
</TouchableOpacity>
<View style={styles.albums}>
{
list.map(function(item, index){
return (
<TouchableOpacity key={index} onPress={this._handlePress}> //doesn't work hehre
<Text>{item}</Text>
</TouchableOpacity>
)
})
}
</View>
</View>
);
}
});
this is referring to the wrong context, you need the scope to be lexically bound, which is what the fat arrow function will do for you.
Try calling your function like this:
onPress={ () => this._handlePress() }
Also, you need to bind the map function to the correct context like this:
<View style={styles.albums}>
{
list.map(function(item, index){
return (
<TouchableOpacity key={index} onPress={() => this._handlePress()}>
<Text>{item}</Text>
</TouchableOpacity>
)
}.bind(this))
}
</View>
Or like this:
<View style={styles.albums}>
{
list.map((item, index) => {
return (
<TouchableOpacity key={index} onPress={() => this._handlePress()}>
<Text>{item}</Text>
</TouchableOpacity>
)
})
}
</View>
I set up a working project here.
https://rnplay.org/apps/_PmG6Q

Categories

Resources