I have ListView Component in a js file and I want to use it another js file and show/hide the component on click of a button dynamically - react-native

How should i do it? My code is :
ListComponent.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
TouchableHighlight
} from 'react-native';
class ListComponent extends Component {
constructor(props) {
super(props);
var dataSource = new ListView.DataSource(
{rowHasChanged: (r1, r2) => r1!== r2});
this.state = {
dataSource: dataSource.cloneWithRows(['A','B','C'])
};
}
renderRow(rowData, sectionID, rowID) {
return (
<TouchableHighlight
<View>
<Text style={styles.instructions}>{rowData}</Text>
</View>
</TouchableHighlight>
);
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}/>
);
}
}
module.exports=ListComponent;
CreateMessage.js
'use strict'
var React= require('react');
var ReactNative = require('react-native');
var {
View,
Text,
Image,
StyleSheet,
TouchableHighlight,
TextInput,
Dimensions,
}= ReactNative;
import { Container, Content, Picker } from 'native-base';
var ListComp=require('./ListComponent');
class CreateMessage extends React.Component{
constructor(props) {
super(props);
this.state = { email: 'Email ID' , pass:'Password', name:'Name', isLoginClicked:'true',language:'ABC',pickerState:false};
}
press(){
this.setState({
pickerState : !this.state.pickerState
});
}
_renderList() {
if (this.state.pickerState) {
return (
<ListComp/>
);
}
else {
return null;
}
}
render(){
return (
<View>
<View>
<View>
<TouchableHighlight
style={{flex:1}}>
<Image
style={styles.headerImage}
source={require('./images/back-arrow.png')}/>
</TouchableHighlight>
<Text> Create Message</Text>
</View>
<View>
<TouchableHighlight>
<Text>Done</Text>
</TouchableHighlight>
</View>
</View>
<View>
<Text>Post to</Text>
<View>
<View>
<Image
style={{height:70,width:70,}}
source={require('./images/no-image.png')}/>
</View>
<View>
<Text
style={styles.text}>name of community</Text>
<Text
style={styles.text1}>no. of members</Text>
</View>
**<TouchableHighlight
underlayColor="gray"
onPress={this.press.bind(this)}>
<Image
style={{height:20,width:20,}}
source={require('./images/add-button.png')}/>
</TouchableHighlight>**
</View>
<Text
style={styles.headingText}>Subject</Text>
<TextInput></TextInput>
<Text
style={styles.headingText}>Message</Text>
<TextInput></TextInput>
<View>
<TouchableHighlight}>
<View>
<Image
style={{height:20,width:20,marginLeft:0,}}
source={require('./images/image-add-button.png')}/>
<Text>Add Photo</Text>
</View>
</TouchableHighlight>
<Text>ADD PROJECT</Text>
</View>
</View>
</View>
);
}
}
module.exports=CreateMessage;
I am displaying CreateMessage.js in my index.ios.js file and it is working fine , but i want to show/hide a list on click of a button (3rd TochableHighlight ).

I assume _renderList is responsible for render your listview component. You can call it in render function.
render(){
return (
<View>
{this._renderList()}
/*......rest of your code....*/
</View>
);

Related

How to create a separate class for a component in react native and use it as a common class?

Hi I am learning react native. I am using Modal component of react native. I need to use the same across multiple times in app. Here the code
Now I am trying to call the function
{this.createModal(dataForMaritalStatus)}
instead of
/* <Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text> : dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
*/
So how to make a common class for this component and pass different arrays of data and use it in render method ? The data is going to be different for different purposes and I need to maintain different states for different purposes.
Edit : I have written a method for it,but it calls the function but it does not render the modal, do I need to render it ?
createModal = (data) => {
<Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{data === null ? <Text style={styles.nodata}>No data Found </Text> : data.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
}
Solution 1
Create a separate file customModalComponent.js, and pass in the array data through props. Change your Modal component a little bit, use this.props.dataForMaritalStatus for dataForMaritalStatus..
<ScrollView showsVerticalScrollIndicator={true}>
{this.props.dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text>
: this.props.dataForMaritalStatus.map((status, id) => (
...
)}
</ScrollView>
and then on any other file, import CustomModal from './customModalComponent' and use it this way,
<CustomModal dataForMaritalStatus={yourArrayOfData}/>
Solution 2
If you are just using it in the same file, create a function instead
class myClass extends Component {
constructor(props) {
super(props);
this.createModal = this.createModal.bind(this);
}
render() {
...
}
createModal(dataForMaritalStatus) {
return (
//Insert your Modal code here
...
)
}
}
and use it this way in your render,
render() {
<View>
...
{
this.createModal(yourArrayOfData)
}
...
</View>
}
create new component in one folder.
app -> CommonModal.js
CommonModal.js
import React, { Component } from 'react';
import { View, Text, Modal, TouchableOpacity } from 'react-native';
export default class CommonModal extends Component{
constructor(props) {
super(props);
}
}
render(){
return(
<Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{this.props.dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text> : this.props.dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
)
}
note: i have used this.props.dataForMaritalStatus
And then use it wherever you need the component
app -> Second.js
Second.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import CommonModal from './CommonModal';
export default class Second extends Component{
constructor(props){
super(props);
this.state={
dataForMaritalStatus:['val1','val2']
}
}
render(){
return(<View style={{flex:1}}>
<CommonModal dataForMaritalStatus={this.state.dataForMaritalStatus}/>
</View>)}
}
Create a separate component for Model
import React, { Component } from "react";
import { Text, View, Modal, ScrollView, TouchableOpacity, Text } from "react-native";
export default class CustomModel extends Component {
render() {
const { dataForMaritalStatus } = this.props;
return (
<Modal
visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false });
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView showsVerticalScrollIndicator={true}>
{dataForMaritalStatus === null ? (
<Text style={styles.nodata}>No data Found </Text>
) : (
dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal();
}}
>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))
)}
</ScrollView>
</View>
</Modal>
);
}
}
don't forget to export that component.
Now import that component in the file where you want to use that
import Model from "./CustomModel";
and use it this way
<CustomModel dataForMaritalStatus=[] />
you can pass data using props like a do above.
you can learn more about props here: https://facebook.github.io/react-native/docs/props

React Native - Is not a function - Is Undefined

I have the following code in React Native
import React from "react";
import {
StyleSheet,
Text,
View,
Button,
TextInput,
Image,
ScrollView
} from "react-native";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
apiData: [],
};
this.getButton();
}
deleteButton(Id){
fetch("http://192.168.2.22:9090/usuario/" + (Id), {
method: "DELETE"
})
.then(responseData => {
console.log(responseData.rows);
})
.done();
this.dataId = null;
}
render() {
const data = this.state.apiData;
let dataDisplay = data.map(function(jsonData) {
return (
<View style={styles.lista} key={jsonData.id}>
<View style={styles.bordeLista}>
<View style={styles.fila}>
<View style={styles.contenedorfoto}>
<Image
style={styles.foto}
source={require("./img/login.png")}
/>
</View>
<View style={styles.datos}>
<Text>Nombre: {jsonData.nombre}</Text>
<Text>E-mail: {jsonData.email}</Text>
<Text>Telefono: {jsonData.telefono}</Text>
</View>
</View>
<View style={styles.fila}>
<View style={styles.contenedorboton}>
<View style={styles.botoniz}>
<Button title="Modificar" onPress={() => {}} />
</View>
<View style={styles.botonde}>
<Button
title="Eliminar"
onPress={() => this.deleteButton(jsonData.Id)}
color="#ee4c4c"
/>
</View>
</View>
</View>
</View>
</View>
);
});
return (
<Text style={styles.titulo}>Usuarios desde BD MySQL</Text>
<ScrollView>
<View>{dataDisplay}</View>
</ScrollView>
</View>
);
}
}
And I want to call deleteButton() from this button
<Button
title="Eliminar"
onPress={() => this.deleteButton(jsonData.Id)}
color="#ee4c4c"
/>
But I get the following error, That the method is not a function and that it is not defined.
Error
How could I use the function? And I'm setting the parameter well (id). Thank you.
PS: I have deleted parts of the code and only left the most important, if you need the full code I can provide it
You're losing the reference to this because you're using an old-style lambda.
Replace this
data.map(function(jsonData) {
with an arrow function, like this
data.map(jsonData => {

Component spinner not working

i create a component call Spinner so:
//spinner.js
import React, { Component } from 'react';
import {
Image,
StyleSheet,
View,
Text,
KeyboardAvoidingView,
TouchableHighlight,
Modal,
Button,
ActivityIndicator,
} from 'react-native';
export default class Spinner extends Component{
constructor(props){
super(props);
this.state={
visible:this.props.visible
};
this._show=this._show.bind(this);
this._hide=this._hide.bind(this);
}
render(){
return(
<Modal
animationType={'none'}
transparent={true}
visible={this.state.visible}
onRequestClose={this.props.onDismissLoadingCallback}>
<View style={{flex:1}}/>
<View style={{
height:80,
width:80,
alignItems:'center',
justifyContent:'center',
backgroundColor:'#3434347f',
borderRadius:10,alignSelf:'center'}}>
<ActivityIndicator
animating={true}
size={"large"}
color={'white'}
/>
</View>
<View style={{flex:1}}/>
</Modal>
);
}
_show() {
this.setState({visible:true});
}
_hide(){
this.setState({visible:false});
}
}
in this create methods _show() and _hide()
but no working when is called from other class, i call from class Login.js
class Login extends Component {
constructor(props) {
super(props)
this.state = { visible: false };
}
_onLoginPress() {
this.Spinner._show()
)
}
_redirect() {
this.Spinner._hide()
}
render() {
return (
<Spinner visible= {this.state.visible}/>
<TouchableHighlight style={styles.button}
onPress={this._onLoginPress}
activeOpacity={1} >
<Text style={styles.textButtonLogin}>Visible</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button}
onPress={this._redirect}
activeOpacity={1} >
<Text style={styles.textButtonLogin}>Not Visible</Text>
</TouchableHighlight>
)
}
when set true in the constructor it if show, but when set false in the constructor it not show, it could show when press button _onLoginPress, and not show when is pressed button _redirect().
For using <Spinner /> reference correctly, you have to
<Spinner ref={(ref) => this.Spinner = ref} visible= {this.state.visible} />
And then your this.Spinner._show(), this.Spinner._hide() should work.

React-native pushing to other class

import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
Image
} from 'react-native';
import First from './First';
export default class Home extends Component{
navSecond(){
this.props.navigator.push({
id: 'First',
title: 'First',
name: 'First',
component: First
})
}
render(){
return(
<View>
<View style={{height:220,backgroundColor:'#DCDCDC'}}>
<Image style={{width:120,height:120,top:50,left:120,backgroundColor:'red'}}
source={require('./download.png')} />
</View>
<View style={{top:30}}>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<TouchableOpacity style= { styles.views} onPress={this.navSecond.bind(this)}>
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Profile </Text>
</TouchableOpacity>
<TouchableOpacity style= { styles.views1} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Health Tracker </Text>
</TouchableOpacity>
</View>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<TouchableOpacity style= { styles.views2} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Medical Care </Text>
</TouchableOpacity>
<TouchableOpacity style= { styles.views3} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Alerts </Text>
</TouchableOpacity>
</View>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<TouchableOpacity style= { styles.views4} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Health Topics </Text>
</TouchableOpacity>
<TouchableOpacity style= { styles.views5} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> My Documents </Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
In this code i need to navigate to First.js using push, but i am not able to do that. By clicking on Profile it should navigate to First.js, here push() is working but that is not navigating to First.js. The above page i set as initial route, then how can i link to all pages?
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity
} from 'react-native';
import Home from './Home';
export default class Prof extends Component{
constructor(){
super()
}
render(){
return (
<Navigator
initialRoute = {{ name: 'Home', title: 'Home' }}
renderScene = { this.renderScene }
navigationBar = {
<Navigator.NavigationBar
style = { styles.navigationBar }
routeMapper = { NavigationBarRouteMapper } />
}
/>
);
}
renderScene(route, navigator) {
if(route.name == 'Home') {
return (
<Home
navigator = {navigator}
{...route.passProps}
/>
)
}
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
if(index > 0) {
return (
<View>
<TouchableOpacity
onPress = {() => { if (index > 0) { navigator.pop() } }}>
<Text style={ styles.leftButton }>
Back
</Text>
</TouchableOpacity>
</View>
)
}
else { return null }
},
RightButton(route, navigator, index, navState) {
if (route.openMenu) return (
<TouchableOpacity
onPress = { () => route.openMenu() }>
<Text style = { styles.rightButton }>
{ route.rightText || 'Menu' }
</Text>
</TouchableOpacity>
)
},
Title(route, navigator, index, navState) {
return (
<Text style = { styles.title }>
{route.title}
</Text>
)
}
};
As your app grows you'll find out that the Navigator is not enough. So I offer you to use react-native-router-flux. It's works well.
you can simply navigate to any scene and send the data as props.
for example :
import React, { Component } from 'react';
import { ... } from 'react-native';
import Actions from 'react-native-router-flux';
export default class Example extends Component {
componentWillMount() {
}
render() {
return (
<View>
<TouchableOpacity
onPress={()=>{ Actions.media({customData: 'Hello!'}) }}
><Text>Navigate to scene Media</Text></TouchableOpacity>
)
}
}
AppRegistry.registerComponent('Example', () => Example);
Navigating to scene Mediaand passing props named customData with value of 'Hello'

Trying to get the modal working in React Native

Attempting to get the modal working on my react native app. I want the more page to display a modal of more options. I have made the following attempt in regards putting the modal in the more menu page. The error I am currently getting is:
MoreMenu.js
import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View } from 'react-native';
class MoreMenu extends Component {
state = {
modalVisible: false,
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType={"slide"}
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight onPress={() => {
this.setModalVisible(!this.state.modalVisible)
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight onPress={() => {
this.setModalVisible(true)
}}>
<Text>Show Modal</Text>
</TouchableHighlight>
</View>
);
}
}
TabsRoot.JS
class Tabs extends Component {
_changeTab (i) {
const { changeTab } = this.props
changeTab(i)
}
_renderTabContent (key) {
switch (key) {
case 'today':
return <Home />
case 'share':
return <Share />
case 'savequote':
return <SaveQuote />
case 'moremenu':
return <MoreMenu />
}
}
render () {
const tabs = this.props.tabs.tabs.map((tab, i) => {
return (
<TabBarIOS.Item key={tab.key}
icon={tab.icon}
selectedIcon={tab.selectedIcon}
title={tab.title}
onPress={() => this._changeTab(i)}
selected={this.props.tabs.index === i}>
{this._renderTabContent(tab.key)}
</TabBarIOS.Item>
)
})
return (
<TabBarIOS tintColor='black'>
{tabs}
</TabBarIOS>
)
}
}
export default Tabs
You forget to export MoreMenu Component. and you use MoreMenu Component in TabsRoot.js.
pls add following line at the end of MoreMenu.js
export default MoreMenu