Update List element by key in React Native - javascript

First off, I've little experience with React and I am still learning the terms.
Basically, what I have is a component that will draw a list based on some JSON obtained through a fetch() call.
What I now need to do is to be able to update each list element based on events received from an EventSource.
The events received from the EventSource will be in the form of {id : data}
Each item on the list has a unique identifier, and based on the events comming in I want to flash an activity indicator on the list with the ID from the event.
I can't figure out how to do this.
I can't seem to directly address any of the items in the list, even though each has a unique ID.
Essentially, I have been searching through google for a solution to this issue, but none of the results I have come across seem to address this issue.
import React from 'react';
import {Text, View, StyleSheet, Button, ScrollView} from 'react-native';
export default class MainFilter extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true};
this.filterURL = this.props.filterURL;
}
componentDidMount(){
init(this.filterURL).then(resp => {
this.setState({
filter: resp['fullFilter'],
filterKeys: resp['filterKeys'],
isLoading: false
});
})
}
render(){
if(this.state.isLoading){
return(
<View>
<Text>Component is LOADING</Text>
</View>
)
}
let filterKeys = this.state.filterKeys;
let fullFilter = this.state.filter;
const filterList = filterKeys.map((item) =>
<View key={item} style={styles.container}>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{borderWidth: 2.5, borderColor: '#00FF00',width: '50%'}}>
<Text style={{fontSize: 19, fontWeight: 'bold'}}>{item}</Text>
<Text style={{fontSize: 16}}>{fullFilter[item]}</Text>
</View>
<View>
<Text>KEKEKEK</Text>
</View>
</View>
<Button key={item} title={"ADD TO FOCUS"} onPress={function() {console.log(item)}}/>
</View>
);
let filterIndex = {};
for(let i = 0; i < filterList.length; i++)
{
filterIndex[filterList[i].key] = filterList[i]
}
console.log(filterIndex);
return(
<ScrollView style={{flex: 1, paddingTop:20}}>
{filterList}
</ScrollView>
);
}
}
const init = async (url) =>{
let response = await fetch(url);
let respJSON = await response.json();
let filterParts = {};
filterParts['filterKeys'] = Object.keys(respJSON);
filterParts['fullFilter'] = respJSON;
return filterParts
};
Essentially what I need to do is to flash an activity indicator on each of the items on the `filterList' constant.
So. How do I do this? Is it possible?
I really want to avoid having to continually redraw the whole component since I don't want to potentially be making hundreds of fetch() calls.

You mean something like this ?
import React from 'react';
import {Text, View, StyleSheet, Button, ScrollView} from 'react-native';
export default class MainFilter extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true};
this.filterURL = this.props.filterURL;
}
componentDidMount(){
init(this.filterURL).then(resp => {
this.setState({
filter: resp['fullFilter'],
filterKeys: resp['filterKeys'],
isLoading: false
});
})
}
filterList(isLoading) {
const {filterKeys, fullFilter} = this.state;
return isLoading ? filterKeys.map((item) => (
<View key={item} style={styles.container}>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{borderWidth: 2.5, borderColor: '#00FF00',width: '50%'}}>
<Text style={{fontSize: 19, fontWeight: 'bold'}}>{item}</Text>
<Text style={{fontSize: 16}}>{fullFilter[item]}</Text>
</View>
<View>
<Text>KEKEKEK</Text>
</View>
</View>
<Button key={item} title={"ADD TO FOCUS"} onPress={function() {console.log(item)}}/>
</View>
) : (
<View>
<Text>Component is LOADING</Text>
</View>
));
}
render(){
let filterIndex = {};
for(let i = 0; i < filterList.length; i++)
{
filterIndex[filterList[i].key] = filterList[i]
}
console.log(filterIndex);
return(
<ScrollView style={{flex: 1, paddingTop:20}}>
{this.filterList(this.state.isLoading)}
</ScrollView>
);
}
}
sorry for the terrible formatting.

Ended up completely redesigning the app.
Facing different problems now.
Question no longer relevant.

Related

How do I access children components of a reference in React Native Web?

I have some references in a React Native Web application - these references work on React Native, but not RNW.
For example, I have this code:
this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })
Which is based on this:
this.highlight = React.createRef();
Which is passed into a child component as a prop and used as such:
<View ref={this.props.highlight}>
It has several children (who have nested children as well).
However, on the web, there is no ._children at all.
How do I access children?
It's possible to do DOM manipulation directly if Platform.OS === 'web':
let dom = ReactDOM.findDOMNode(this.highlight.current);
... DOM manipulations
But this feels messy and code-duplicating if not absolutely necessary. I'd much rather apply my modifications to the reference directly via the React Native API.
EDIT: More code - here's my structure and a few relevant functions to the problem. I cut out irrelevant parts to try to make the code I posted smaller
class DetailBody extends Component {
constructor() {
super();
}
render() {
return (
<ScrollView >
<Text>{this.props.article.intro}</Text>
<View ref={this.props.highlight}>
{this.props.article.json.results.map((content, index) => (
<View key={index} style={{}}>
{content.pinyin ? (
<Fragment>
<View>
<Text>
{content.pinyin}
</Text>
</View>
<View>
<Text>
{content.simplified}
</Text>
</View>
</Fragment>
) : (
<Fragment>
<View>
<Text>
</Text>
</View>
<View>
<Text>
{content.characters}
</Text>
</View>
</Fragment>
)
}
</View>
))}
</View>
</ScrollView>
)
}
}
class Detail extends Component {
constructor() {
super();
this.state = {
currentVal: 0,
};
this.traverseCharacters = this.traverseCharacters.bind(this)
this.highlight = React.createRef();
}
async traverseCharacters(i) {
this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })
if (i > 0) {
this.clearCharacters(i)
}
}
render() {
return (
<DetailBody {...this.props} article={this.state.article} highlight={this.highlight} />
);
}
}
[Edit]: Since this 'someone's work' is for class component, here is one of my answer using dynamic refs with a functional component : Dynamic refs with functional component. It uses a useRef() hooks to store your dynamic refs, and so they're accessible wherever you want, with a specific id.
After trying things for a moment now, I cannot find a clean way of doing what you want to do. However, there is solutions for this, as you said with the ReactDOM. Another thing that came in my mind would be to set your refs in your child and then pass it to the parent.
Here is someone doing 'dynamic' ref in a .map using the key attribute, maybe it can be of use to you : Someone's work
Now, using direct manipulation isn't a good practice, so using this isntead of ReactDOM.findDOMNode... I don't really know which is one is worse but both are messy i guess.
setNativeProps isn't available on the children element. You either need to provide a refs to the intended child elements yourself before calling setNativeProps on them
For a ref solution you could make use of ref callbacks like below and add a ref to each and every element that you wish to update dynamically
class DetailBody extends Component {
setRef = (i, j, ref) => {
if(this.highlight[i]) {
this.highlight[i][j] = ref;
} else {
this.highlight[i] = {[j]: ref};
}
}
render() {
return (
<ScrollView >
<Text>{this.props.article.intro}</Text>
<View>
{this.props.article.json.results.map((content, index) => (
<View key={index} style={{}} ref= {(ref) => this.setRef(index, 'root', ref)}>
{content.pinyin ? (
<Fragment>
<View ref= {(ref) => this.setRef(index, 0, ref)}>
<Text>
{content.pinyin}
</Text>
</View>
<View ref= {(ref) => this.setRef(index, 1, ref)}>
<Text>
{content.simplified}
</Text>
</View>
</Fragment>
) : (
<Fragment>
<View ref= {(ref) => this.setRef(index, 0, ref)}>
<Text>
</Text>
</View>
<View ref= {(ref) => this.setRef(index, 1, ref)}>
<Text>
{content.characters}
</Text>
</View>
</Fragment>
)
}
</View>
))}
</View>
</ScrollView>
)
}
}
class Detail extends Component {
constructor() {
super();
this.state = {
currentVal: 0,
};
this.traverseCharacters = this.traverseCharacters.bind(this)
this.highlight = {};
}
async traverseCharacters(i) {
this.highlight[i].root.setNativeProps({ style: { backgroundColor: "black" } });
this.highlight[i][0].setNativeProps({ style: { color: "white" } })
this.highlight[i][1].setNativeProps({ style: { color: "white" } })
}
render() {
return (
<DetailBody {...this.props} article={this.state.article} highlight={this.highlight} />
);
}
}

proper use of callback function in react native

Disclaimer: Pretty novice in javascripting and react-native :)
I am trying a very simple application in react native. User is presented with a screen where two numbers and an operator is given (like +, - etc) and user will enter result in the text field provided. As in the screenshot below
To facilitate the application I have two main classes:
1) Parent Class (which basically generate the numbers, pass to the child as props, gets the result in callback function and if result is correct regenerates the numbers again)
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
Text,
Button
} from 'react-native';
import BasicBox from '../components/BasicBox';
export default class example extends Component {
constructor() {
super();
this.state = {
result: 0
};
this.generate()
}
getResponse(result){
let text=""
for (var i = 0; i < result.length; i++) {
text += result[i];
}
console.log(result)
if (this.expected_result === parseInt(text))
{
this.generate()
}
this.setState({result:parseInt(text)})
}
generate() {
this.length = 3
this.number_1 = Math.floor(Math.random() * 1000)
this.number_2 = Math.floor(Math.random() * 1000)
this.result_box_count = this.length + 1
this.operator="+"
this.expected_result = eval (this.number_1 + this.operator + this.number_2)
console.log(this.number_1)
console.log(this.number_2)
console.log(this.expected_result)
// this.setState({result:this.expected_result})
}
render() {
//this.generate();
return (
<View>
<BasicBox
number_1={this.number_1}
number_2={this.number_2}
operator={this.operator}
result_box_count={this.result_box_count}
get_result = {this.getResponse.bind(this)}
/>
<Text>
{console.log(this.expected_result)}
{console.log(this.state.result)}
{this.state.result===this.expected_result ? "": "Oh Boy!" }
</Text>
</View>
);
}
}
2) child class (which takes numbers generated from parent, and returns the result to parent, on button press)
import React, { Component } from 'react';
import {Text, TextInput, Image, View, StyleSheet, Button} from "react-native"
export default class BasicBox extends Component {
constructor() {
super();
this.state = {
result: ["","","",""]
};
}
render(){
return (<View>
<View style={styles.main}>
<View>
<View style={styles.operand}>
<Text style={styles.digit}>{Math.floor(this.props.number_1/100)}</Text>
<Text style={styles.digit}>{Math.floor(this.props.number_1/10%10)}</Text>
<Text style={styles.digit}>{this.props.number_1%10}</Text>
</View>
<View style={styles.operand}>
<Text style={styles.digit}>{Math.floor(this.props.number_2/100)}
</Text>
<Text style={styles.digit}>{Math.floor(this.props.number_2/10%10)}</Text>
<Text style={styles.digit}>{this.props.number_2%10}</Text>
</View>
<View style={styles.operand}>
<View>
<Text style={styles.digit_hidden} >1</Text>
<TextInput style={styles.digit_answer}
keyboardType='numeric'
maxLength={1}
onChangeText={(txt)=>{
result=this.state.result;
result[0]=txt
this.setState({result:result})
}}
>
</TextInput>
</View>
<View>
<Text style={styles.digit_hidden}>1</Text>
<TextInput style={styles.digit_answer}
keyboardType='numeric'
maxLength={1}
onChangeText={(txt)=>{
result=this.state.result;
result[1]=txt
this.setState({result:result})
}
}
>
</TextInput>
</View>
<View>
<Text style={styles.digit_hidden}>1</Text>
<TextInput style={styles.digit_answer}
keyboardType='numeric'
maxLength={1}
onChangeText={(txt)=>{
result=this.state.result;
result[2]=txt,
this.setState({result:result})
}}
></TextInput>
</View>
<View>
<Text style={styles.digit_hidden}>1</Text>
<TextInput style={styles.digit_answer}
keyboardType='numeric' maxLength={1}
onChangeText={(txt)=>{
result=this.state.result;
result[3]=txt,
this.setState({result:result})
}}
></TextInput>
</View>
</View>
</View>
<View>
<Text style={styles.digit}>{this.props.operator}</Text>
</View>
</View>
<Button onPress={()=>{this.props.get_result(this.state.result)}}
title="Check Result"
/>
</View>)
}
}
const styles = StyleSheet.create ({
main: {
flexDirection:"row",
// borderWidth:1,
// flex: 1,
justifyContent: "center",
// alignItems: "center"
},
digit: {
fontSize: 80,
// borderWidth:1,
//adjustsFontSizeToFit
},
digit_hidden: {
fontSize: 80,
// borderWidth:1,
flex:1,
// color: `rgb(255,255,255)`
},
operand: {
flexDirection:"row",
justifyContent:"flex-end",
// alignItems:"flex-end",
// borderWidth:1,
},
digit_answer: {
// alignItems:"baseline",
// flexDirection:"row",
// justifyContent:"flex-end",
// backgroundColor: `rgb(255,255,255)`,
// alignItems:"flex-end",
fontSize: 80,
// backgroundColor: gray`rgb(255,255,255)`,
backgroundColor:'gray',
borderWidth:1,
},
});
Thank you for reading so far :)
In my class definitions, Button is in my child class because I want to send results to parent in OnPress. For UI My questions are:
1) Most importantly, How can I move the Button to my parent class and get the result somehow back to my parent from the child class?
2) My TextInput fields in < BasicBox> don't get cleared when numbers are regenerated. What's wrong here?
You need to use the UNSAFE_componentWillReceive method in child component when the parent component value changes

typeError: undefined is not an object (evaluating 'item.phoneNumbers[0]')

I want to render my contact list in my app using expo-contacts, the list display for about 2 seconds, then i get typeError: undefined is not an object (evaluating 'item.phoneNumbers[0]'). I have checked the documentation to see if I made any errors, but i could not find any. Does anyone have a work around this
below is my code
ContactList.js
import React, { Component } from "react";
import {
View,
Text,
Platform,
StatusBar,
FlatList,
StyleSheet,
ActivityIndicator
} from "react-native";
import * as Contacts from "expo-contacts";
import * as Permissions from "expo-permissions";
class ContactList extends Component {
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
isLoading: false,
contacts: []
};
}
async componentDidMount() {
this.setState({
isLoading: true
});
this.loadContacts();
}
loadContacts = async () => {
const permissions = await Permissions.askAsync(Permissions.CONTACTS);
if (permissions.status !== "granted") {
return;
}
const { data } = await Contacts.getContactsAsync({
fields: [Contacts.Fields.PhoneNumbers, Contacts.Fields.Emails]
});
this.setState({
contacts: data,
isLoading: false
});
};
handleBack() {
this.props.navigation.goBack();
}
renderItem = ({ item }) => (
<View style={{ minHeight: 70, padding: 5 }}>
<Text>
{item.firstName}
{item.lastName}
</Text>
<Text>{item.phoneNumbers[0].digits}</Text>
</View>
);
render() {
const { isLoading, contacts } = this.state;
let emptyContact = null;
emptyContact = (
<View style={styles.emptyContactStyle}>
<Text style={{ color: "red" }}>No Contacts Found</Text>
</View>
);
return (
<SafeAreaView style={styles.contentWrapper}>
<View style={styles.contentWrapper}>
{isLoading ? (
<View style={styles.isLoadingStyle}>
<ActivityIndicator size="large" color="#2484E8" />
</View>
) : null}
<FlatList
data={contacts}
renderItem={this.renderItem}
keyExtractor={(item, index) => index.toString()}
ListEmptyComponent={emptyContact}
/>
</View>
</SafeAreaView>
);
}
}
Here is a new answer because the previous one was off topic. The error occurs because the displayed contact doesn't have a phoneNumber.
You should check first that a phone number exists before displaying it:
renderItem = ({ item }) => (
<View style={{ minHeight: 70, padding: 5 }}>
<Text>
{item.firstName}
{item.lastName}
</Text>
<Text>
{item.phoneNumbers && item.phoneNumbers[0] && item.phoneNumbers[0].digits}
</Text>
</View>
);

Create rows in React Native

i want to create rows for images,which recieve from _find function.This function already seperated array to subarrays,which number equals number of rows,how i can render rows with data from _find?Dont purpose ready solutions such as react-native-easy-grid,i want to do it without another libs,and can i scroll items if i use this way?
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View,StyleSheet,Button,Image,ScrollView,Dimensions,ListView } from 'react-native';
import Grid from './GridBuilder.js';
const regUrl = /(src=")?(https:\/\/\S{2,500})(")/gm;
var IMAGES_PER_ROW = 3;
let app1;
export default class inputText extends Component {
constructor(props) {
super(props);
app1 = this;
this.state = {
text: null,
findEvent:false,
im_p_r:3,
items:{},
};
}
render() {
return (
<View style={{margin: 20}}>
<TextInput
style = {styles.searchInput}
placeholder="Type here to search"
onChangeText={(text) => this.setState({text})}
/>
<Button
onPress={() => this._find(this.state.text)}s
title='Find'
color="#841584"
accessibilityLabel="on"
/>
{this.state.findEvent && <DisplayImage />}
</View>
);
}
_find(searchText){
fetch('https://www.googleapis.com/customsearch/v1?key=AIzaSyAfcN3jfimFxHxpHNjhHOSuuY8dm5YZnqQ&cx=007223195539364418542:lcqjo0djp7k&num=10&q='+ searchText+'&searchType=image')
.then((resp) => resp.json())
.then(function(data) {
let s = data.items;
let SIZE = IMAGES_PER_ROW;
let res = s.reduce((p,c)=>{
if(p[p.length-1].length == SIZE){
p.link.push([]);
}
p[p.length-1].push(c);
return p.link;
}, [[]])
app1.setState({items:res,findEvent:true});
})
}
}
export class DisplayImage extends Component {
render(){
return(
<View style={styles.container}>
{app1.state.items.map((item,index) => <View style={styles.row} ><Image style={[styles.image,styles.box]} source={{uri:item.link}} key={index} /></View>)}
</View>
)
}
}
const styles = StyleSheet.create({
searchInput:{
fontSize:20,
paddingTop:20,
paddingBottom:20
},
image:{
paddingTop:20,
width:100,
height:100,
},
row: {
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
justifyContent: 'space-between'
},
box: {
flex: 1,
height: 100,
width:100,
backgroundColor: '#333',
},
})
AppRegistry.registerComponent('inputText', () => inputText);
AppRegistry.registerComponent('DisplayImage', () => DisplayImage);
You can use FlatList from React Native.
{this.state.findEvent && <FlatList
data={this.state.items}
renderItem={({ item }) => this.renderItem(item)}
/>}
FlatList receive as data the list of elements you want to render, in this case the data returned from the find function.
And then define the renderItem function like:
renderItem(item) {
return (
<View style={styles.row} >
<Image
style={[styles.image,styles.box]}
source={{uri:item.link}} key={index}
/>
</View>
);
}
This function is in charge of rendering the list of images, each image as a row as you want.
FlatList is really useful and makes lists rendering easier. You get the scroll by default and you can also render separators, have a pull to refresh, etc. Take a look to the FlatList doc to see all properties available.
Here is working example of Flat list by which you can get images in the row
https://snack.expo.io/SJDoljDg7
FlatList is the way to go but I suspect the spec has changed since the original accepted answer. You must now provide a key extractor, here is an example of what worked for me:
const listItems = [
{
"id": 0.7967679550647925,
"name": "Hcsrhjkh",
},
{
"id": 0.3212834674770011,
"name": "Phvdgbb",
},
{
"id": 0.30092504022778455,
"name": "Hnvdghbh",
},
]
...
{listItems.length < 1 ? (
<Text style={{ fontSize: 30 }}>Your list is empty.</Text>
) : (
<FlatList
data={listItems}
renderItem={({item}) => <ListItem item={item} />}
keyExtractor={(item) => item.id.toString()}
/>
)}
As you can might have found, the keyExtractor expects a string so I've coerced the 'id' which is a number to a string.

Programmatically add a component in React Native

Suppose I have a simple React Native app like so:
'use strict';
var React = require('react-native');
var {
AppRegistry,
Text,
TouchableHighlight,
View,
} = React;
var ReactProject = React.createClass({
_onPressOut: function() {
// What do we do here?
},
render() {
return (
<View>
<Text>This text should be before</Text>
<Text>This text should be after</Text>
<TouchableHighlight onPressOut={this._onPressOut}>
<Text>Tap Me</Text>
</TouchableHighlight>
</View>
);
}
});
AppRegistry.registerComponent('ReactProject', () => ReactProject);
How can I dynamically insert a component between the first and second Text tags when the TouchableHighlight is pressed?
Try creating an array and attaching it to the state. You can then push items to the array, and reset the state.
https://rnplay.org/apps/ymjNxQ
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight
} = React;
var index = 0
var SampleApp = React.createClass({
getInitialState(){
return { myArr: [] }
},
_onPressOut() {
let temp = index ++
this.state.myArr.push(temp)
this.setState({
myArr: this.state.myArr
})
},
render() {
let Arr = this.state.myArr.map((a, i) => {
return <View key={i} style={{ height:40, borderBottomWidth:2, borderBottomColor: '#ededed' }}><Text>{ a }</Text></View>
})
return (
<View style={styles.container}>
<Text>First</Text>
{ Arr }
<Text>Second</Text>
<TouchableHighlight style={ styles.button } onPress={ () => this._onPressOut() }>
<Text>Push</Text>
</TouchableHighlight>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
marginTop:60
},
button: {
height:60,
backgroundColor: '#ededed',
marginTop:10,
justifyContent: 'center',
alignItems: 'center'
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
I've set up a working example here.
In react or react native the way component hide/show or add/remove does not work like in android or iOS. Most of us think there would be the similar stratedgy like
View.hide = true or parentView.addSubView(childView
But the way react native work is completely different. The only way to acheive this kind of functionality is to include your component in your DOM or remove from DOM.
Here in this example I am going set the visibility of text view based on the button click.
enter image description here
The idea behind this task is the create a state variable called state having the initial value set to false when the button click event happens then it value toggles. Now we will use this state variable during the creation of component.
import renderIf from './renderIf'
class fetchsample extends Component {
constructor(){
super();
this.state ={
status:false
}
}
toggleStatus(){
this.setState({
status:!this.state.status
});
console.log('toggle button handler: '+ this.state.status);
}
render() {
return (
<View style={styles.container}>
{renderIf(this.state.status)(
<Text style={styles.welcome}>
I am dynamic text View
</Text>
)}
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text> touchme </Text>
</TouchableHighlight>
</View>
);
}
}
the only one thing to notice in this snippet is renderIf which is actually a function which will return the component passed to it based on the boolean value passed to it.
renderIf(predicate)(element).
renderif.js
'use strict';
const isFunction = input => typeof input === 'function';
export default predicate => elemOrThunk =>
predicate ? (isFunction(elemOrThunk) ? elemOrThunk() : elemOrThunk) : null;
With React components you don't want to think of actions reaching into the DOM and inserting components - you want to think components responding to actions. Theoretically, this component is already composed and ready, it just needs to know if it should be rendered or not:
var ReactProject = React.createClass({
getInitialState() {
// our *state* dictates what the component renders
return {
show: false
};
}
_onPressOut: function() {
// update our state to indicate our "maybe" element show be shown
this.setState({show: !this.state.show});
},
maybeRenderElement() {
if (this.state.show) {
// depending on our state, our conditional component may be part of the tree
return (
<Text>Yay!</Text>
);
}
return null;
}
render() {
return (
<View>
<Text>This text should be before</Text>
{this.maybeRenderElement()}
<Text>This text should be after</Text>
<TouchableHighlight onPressOut={this._onPressOut}>
<Text>Tap Me</Text>
</TouchableHighlight>
</View>
);
}
});
I've also made a helper that makes it easy to conditionally render things, render-if
renderIf(this.state.show)(
<Text>Yay</Text>
)
ECMA6 Syntax
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
TouchableHighlight
} from 'react-native';
export default class fourD extends Component {
constructor(props) {
super(props);
let ele1 = (
<View key={1}>
<Text>Element {1}</Text>
<TouchableOpacity onPress={ () => this._add() }>
<Text>Add</Text>
</TouchableOpacity>
</View>
);
this.state = {
ele: [],
key: 1
}
this.state.ele.push(ele1);
}
_add(){
let key = this.state.key + 1;
let ele2 = (
<View key={key}>
<Text>Element {key}</Text>
<TouchableOpacity onPress={ () => this._add() }>
<Text>Add</Text>
</TouchableOpacity>
</View>
);
let ele = this.state.ele;
ele.push(ele2);
this.setState({ ele: ele,key : key})
}
render() {
return (
<View style={styles.container}>
<Text>This text should be before</Text>
{ this.state.ele }
<Text>This text should be after</Text>
<TouchableHighlight onPressOut={ () => this._add() }>
<Text>Tap Me</Text>
</TouchableHighlight>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
}
})

Categories