Reputation: 345
I've got a component, let's call Screen, which imports a component that will contain a search result. A method in Screen loops through an array of objects and for each object instaniates a new search result component and stores them in an array.
I'm new to React, so my question is, is it correct to create an instance of a class extending Component using the new
keyword, or is there a proper React way to do this? If so what is the correct way of rendering these components in the Screen class, as the way I'm doing it in the snippet below doesn't seem to work as nothing renders.
Screen.js - I've cut down the file to just show what I'm on about
import React, { Component } from "react";
import { Text, View } from "react-native";
import SearchResult from "components/SearchResult";
class Screen extends Component {
searchResultsComponents = [];
submitSearchQuery(searchParam /* Array of objects */) {
this.searchResultsComponents = [];
for(let result in this.searchResults) {
this.searchResultsComponents.push(new SearchResult(this.searchResults[result]));
}
this.forceUpdate();
});
}
render() {
return(
<View>
{ this.searchResultsComponents.forEach((it) => { it.render(); }) }
</View>
);
}
}
export default Screen;
SearchResult.js
import React, { Component } from "react";
import { Text, View } from "react-native";
class SearchResult extends Component {
title;
setTitle(title) {
this.title = title;
}
getTitle() {
return this.title;
}
description;
setDescription(description) {
this.description = description;
}
getDescription() {
return this.description;
}
constructor(searchResult) {
super();
this.setTitle(searchResult.snippet.title);
this.setDescription(searchResult.snippet.description)
}
render() {
return(
<View>
<Text>{ this.title }</Text>
<Text>{ this.description }</Text>
</View>
);
}
}
export default SearchResult;
Upvotes: 3
Views: 6206
Reputation: 1631
The reason your approach doesn't work is that forEach
method doesn't return anything. Instead of forEach
use map
. Your modified line should look something like this:
this.searchResultsComponents.map((component, index) => <View key={index}>{component}</View>);
The reason I wrapped the component into View
is because this way each item can get key
attribute which is recommended when displaying arrays.
Upvotes: 1
Reputation: 3909
The proper way to approach this is, inside your render method:
{ this.searchResultsComponents.map((it, index) => <it key={index} />) }
The key is optional, but recommended by react to improve rendering performance when rendering an array of components.
See https://reactjs.org/docs/lists-and-keys.html#basic-list-component for more details.
Your approach does not work, because by just calling the render method, the HTML DOM is returned by the function call. However, you just call the function and don't do anything with the return value.
Upvotes: 2