Raw text "" must be wrapped in explicit text component - react-native

I am using a react native component listview to render nested items as follows:
constructor() {
super();
this.renderRow = this.renderRow.bind(this);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
[
{'main':'q', 'sub': 'y'}
],
[
{'main':'x', 'sub': 'f'},
{'main':'c', 'sub': 'b'}
]
]),
};
}
renderRow(rowData, section, row) {
const total = this.state.dataSource.getRowCount();
let rowView = rowData.map( x => {
return <View> <Text>{x['main']}</Text> <Text>{x['sub']}</Text> </View>
})
return (
<View>
{rowView}
</View>
);
}
render() {
return (
<View style={styles.container}>
<ListView style={styles.listView}
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
</View>
);
}
But I am getting following error:
Raw text "" must be wrapped in explicit text component.
I am unable to track where I am getting this error from.

let rowView = rowData.map( x => {
return <View> <Text>{x['main']}</Text> <Text>{x['sub']}</Text> </View>
})
Remove spaces between View And Text Components. Use tab and enter instead of space character.
let rowView = rowData.map( x => {
return <View>
<Text>{x['main']}</Text>
<Text>{x['sub']}</Text>
</View>
})

To solve this, I used regex search & replace in entire file, and replacing >(\s)+<Text with ><Text works.

Mainly this issue arise due to space between <View> <Text> etc
A trick fix for this issue could be execute Format Document (I am using VScode (IDE), you can try with any IDE which have code styling capability). By Style fixing spaces between tags gets automatically removed.

Related

My if statement is not working in React Native

I want to build a search bar that filters a flatlist in react native. I'm doing so with a TextInput and a component SearchFilter.
In my homescreen I have this TextInput:
<TextInput
value={input}
onChangeText={(text) => setInput(text)}
style={{ fontSize: 16, marginLeft: 10 }}
placeholder="Search"
/>
And this component:
<SearchFilter data={Cars} input={input} setInput={setInput} />
In the component file I have my flatlist:
const searchFilter = (data, input, setInput) => {
console.log(input)
return (
<View>
<Text>SearchFilter</Text>
<FlatList
style={styles.list}
data={data}
renderItem={({ item }) => {
if (input === "") {
return (
<View>
<Text>test</Text>
</View>
)
}
}}
></FlatList>
</View>
);
};
When nothing is being searched I want test to be displayed.
The problem is that it shows nothing.
When I do a console.log(input) in my homescreen the console returns an emty string
but when I do a console.log(input) in my component file it returns {}. I do not know why. When I tried
if (input === " {}") {
return (
<View>
<Text>test</Text>
</View>
)
}
it also did not work.
Any asolutions?
I suppose the searchFilter is your component ?
If it is the case then you don't use the props correctly, try like this :
const SearchFilter = ({data, input, setInput}) => { ... rest of your code ... }
You can't compare a object like this, it's not the same (in the memory).
Assuming var x = {}
x == {} // false (it's the same 'content' but it's not saved at the same place in the memory
x == "{}" // false (x is a object "{}" is a string)`
Assuming var y = x
y == x // true
To compare basic object, you can use JSON.stringify() function, it's parse object to string like this : (JSON.stringify(x) == JSON.stringify({})) === true
It's explain why your condition doesn't work but I don't know why do you have a object as output (I'm not a react developer ^^)
I hope it's even be usefull for you

nothing was returned from render but can't be fixed

I don't know what I did wrong in this function, I thought I had a return but I don't think it's being considered, and when I change the closing brackets or parenthesis it shows an error :/
Can someone help me?
function PopSheet() {
let popupRef = React.createRef()
const sheet =() => {
const onShowPopup =()=> {
popupRef.show()
}
const onClosePopup =()=> {
popupRef.close()
}
return (
<SafeAreaView style ={styles.container}>
<TouchableWithoutFeedback onPress={onShowPopup}>
</TouchableWithoutFeedback>
<BottomPopup
title="Demo Popup"
ref ={(target) => popupRef =target}/>
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}
};
You need to use the render function which is responsible for rendering or display the JSX element into your app.
render() {
return (
<SafeAreaView style={styles.container}>
<TouchableWithoutFeedback
onPress={onShowPopup}></TouchableWithoutFeedback>
<BottomPopup title="Demo Popup" ref={target => (popupRef = target)} />
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}

what react native component for creating list with sub item

what react native component for creating list with sub items? I checked the docs, it could be flatlist, but flatlist doesn't say anything about sliding in sub item.
You can use <FlatList> for efficient displaying of a large list. This <FlatList> is recommended if you have a large list. Then you can contain each content of a list in <TouchableWithoutFeedback> and provide onPress event handler.
for eg.
<FlatList>
<TouchableWithoutFeedback onPress={/*---include your selection logic here*/}>
/* your content come here */
</TouchableWithoutFeedback>
</FlatList>
Also, if you want to apply animation to drop down list I would recommend you to use <LayoutAnimation>
You can use react-native-collapsible.
it will help you to achieve same things and you can design your own styling by creating customizable view.
Installation
npm install --save react-native-collapsible
Example
import React, { Component } from 'react-native';
import Accordion from 'react-native-collapsible/Accordion';
const SECTIONS = [
{
title: 'First',
content: 'Lorem ipsum...'
},
{
title: 'Second',
content: 'Lorem ipsum...'
}
];
class AccordionView extends Component {
state = {
activeSections: []
};
_renderSectionTitle = section => {
return (
<View style={styles.content}>
<Text>{section.content}</Text>
</View>
);
};
_renderHeader = section => {
return (
<View style={styles.header}>
<Text style={styles.headerText}>{section.title}</Text>
</View>
);
};
_renderContent = section => {
return (
<View style={styles.content}>
<Text>{section.content}</Text>
</View>
);
};
_updateSections = activeSections => {
this.setState({ activeSections });
};
render() {
return (
<Accordion
sections={SECTIONS}
activeSections={this.state.activeSections}
renderSectionTitle={this._renderSectionTitle}
renderHeader={this._renderHeader}
renderContent={this._renderContent}
onChange={this._updateSections}
/>
);
}
}
You can customize the view by using Properties

React Native - Trying to print depending on the state of index

I am trying to loop through this array and print out the quote, depending on if it is saved as true or false.
At the moment, it just prints out in the JSON array. I'm new to react native, so not 100% certain of the behaviour of map.
var savedQuote = quotes.quotesArray.map(quote => quote.isSaved)
{
quotes.quotesArray.map((quote, i) => {
if(savedQuote){
return(
<TouchableOpacity key={i} style = {styles.border}>
<Text style = {styles.text}>
i: {i}. {quotes.quotesArray[i].preview}
</Text>
</TouchableOpacity>
)
}
else{
return <Text key = {i}>{i}Nada</Text>
}
})
}
I don't understand why you have two map in your code. One should suffice :
quotes.quotesArray.map((quote, i) => {
if(quote.isSaved){
return(
<TouchableOpacity key={i} style = {styles.border}>
<Text style = {styles.text}>
i: {i}. {quote.preview}
</Text>
</TouchableOpacity>
)
} else {
return <Text key = {i}>{i}Nada</Text>
}
});
This will loop through quotes and either return one node or the either if quote.isSaved is true or not.
you could save them to a new array if you assign it to a new variable ex: var savedQuotes = ... or use it inside your render function :
render() {
return (
<View>
{quotes.quotesArray.map...}
</View>
);
}
The map() method creates a new array with the results of calling a
provided function on every element in this array.
Here is more information: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Here are some examples from the react documentation : https://facebook.github.io/react/docs/lists-and-keys.html (which should be close enough to react-native)

React Native list view data parsing from JSON

This is the JSON im trying to parse and show in my list view.
The data I would like to show on my list view is ZoneInfo["Name"] as a section header. For the list view, there would be 3 text showing the Name,QueueTime or ShowTime.
I have my JSON saved in my state variable.
This is the code I've been trying to retrieve the data from the JSON.
{this.state.loading? <Spinner /> : <List dataArray={this.state.results.items} renderRow={(item) =>
<ListItem>
<Text>{item}</Text>
</ListItem>
} />}
Anyone can guide me on how I can parse the JSON and show it on my listview?
There are for sure multiple ways of achieving this, up till now I'm pretty happy using it this way:
I'm sure you will find your way around ;-)
export default class extends React.Component {
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.renderSectionHeader = this.renderSectionHeader.bind(this);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2});
this.state = {
dataSource: ds.cloneWithRowsAndSections({}),
};
}
componentDidMount(){
... load your json and assign data to the state
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(spots)
});
}
renderRow(rowData: string, sectionID: number, rowID: number) {
return (
<TouchableOpacity onPress={()=>this.onRowPress(rowData)}>
... your row content
</TouchableOpacity>
)
}
renderSectionHeader(sectionData, category) {
return (
<View style={styles.rowHeaderContainer}>
... your header content
</View>
)
}
render(){
return (
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
enableEmptySections={true}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
}
}