React native components not working properly - react-native

I have this custom button component :
import React, { Component } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { styles } from "./styles";
class TransactionFees extends Component {
test = () => {
const { speed, eth, usd,pressed,changeColor } = this.props;
console.log("speed, eth, usd,pressed,changeColor",speed, eth, usd,pressed,changeColor)
}
render() {
const { speed, eth, usd,pressed,changeColor,key } = this.props;
return (
<TouchableOpacity style={ pressed ? styles.pressedButton : null } onPress={changeColor}>
<Text style={styles.transactionFeeTitle}>{speed}</Text>
<Text style={styles.transactionFeeSubText}>{eth} ETH</Text>
<Text style={styles.transactionFeeSubText}>$ {usd} </Text>
</TouchableOpacity>
);
}
}
export default TransactionFees;
This is how I use it:
<TransactionFees pressed={pressed} changeColor={this.changeColor} key={"slow"} speed={"Slow"} eth={"0.000010"} usd={"0.02"} />
<TransactionFees pressed={pressed} changeColor={this.changeColor} key={"average"} speed={"Average"} eth={"0.000030"} usd={"0.03"} />
<TransactionFees pressed={pressed} changeColor={this.changeColor} key={"fast"} speed={"Fast"} eth={"0.000050"} usd={"0.04"} />
changeColor function:
changeColor = () => {
const {pressed} = this.state
this.setState({pressed:!pressed})
}
When clicked I want only one of them to change the background style but the problem is when clicking on any of them,all of them change the background stye any solutions on how to solve this please?

You will have to maintain the pressedKey in the parent instead of maintaining the pressed something like below. Here we pass the selected key using the changeColor and maintain that in the parent which will be used to compare and decide the backgroud color.
class TransactionFeesContainer extends Component {
state = {
selectedKey: null,
};
changeColor = (key) => {
this.setState({ selectedKey: key });
};
render() {
return (
<View>
<TransactionFees
selectedKey={this.state.selectedKey}
changeColor={this.changeColor}
speedkey={'slow'}
speed={'Slow'}
eth={'0.000010'}
usd={'0.02'}
/>
<TransactionFees
selectedKey={this.state.selectedKey}
changeColor={this.changeColor}
speedkey={'average'}
speed={'Average'}
eth={'0.000030'}
usd={'0.03'}
/>
<TransactionFees
selectedKey={this.state.selectedKey}
changeColor={this.changeColor}
speedkey={'fast'}
speed={'Fast'}
eth={'0.000050'}
usd={'0.04'}
/>
</View>
);
}
}
class TransactionFees extends Component {
render() {
const { speed, eth, usd, speedkey, selectedKey } = this.props;
return (
<View>
<TouchableOpacity
style={speedkey === selectedKey ? styles.pressedButton : null}
onPress={() => {
this.props.changeColor(speedkey);
}}>
<Text style={styles.transactionFeeTitle}>{speed}</Text>
<Text style={styles.transactionFeeSubText}>{eth} ETH</Text>
<Text style={styles.transactionFeeSubText}>$ {usd} </Text>
</TouchableOpacity>
</View>
);
}
}

Related

I built my own button component and I can't get it to work

I built my own button component using React Native and I am trying to use it in my code. All I am trying to do for now is to get it to log a console message and for some reason it's not doing it.
Button Component
import React, {Component} from 'react';
import { Text, TouchableOpacity } from 'react-native';
class Button extends Component {
render(){
const { onPress, children } = this.props;
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={ onPress } style={ buttonStyle }>
<Text style={ textStyle }>
{ children }
</Text>
</TouchableOpacity>
);
}
}
Code using the Button
class FlashcardMenuDetail extends Component {
onButtonPress() {
console.log('You pushed the button');
}
render() {
const { title } = this.props.flashcard;
return (
<Card>
<CardItem>
<Button onpress={this.onButtonPress.bind(this)}>
{ title }
</Button>
</CardItem>
</Card>
);
}
}
I can push the button but nothing shows up on the console window.
There is no arrow function in the button you made onPress When the function of the function is used, only the console log is left because the return value is imported. You have to add an arrow function.
export const makeButton = (props) => {
const { title = "title", buttonStyle = {}, textStyle = {}, onPress } = props;
return (
<TouchableOpacity onPress={() => onPress} style={buttonStyle}>
<Text style={textStyle}>{props.title}</Text>
</TouchableOpacity>
);
};
Usage
import { makeButton } from 'path/makeButton.js';
<Card>
<CardItem>
<makeButton
title="get console.log"
onPress={() => onButtonPress() }
buttonStyle ={{ /* some styles for button */ }}
textStyle={{ /* styles for button title */ }}
/>
</CardItem>
</Card>

How to change text in sibling component in react-native?

I have an 'OutputBox' component and want to change the text being displayed in the component when I click a button.
I've read about props and state and i can't seem to get them working the way i need them too. I just started react-native and have a heavy background c++. I thought i could just declare a variable, 'text' in the 'OutputBox' component and then call a 'setOutputBoxText' function and change the 'text' var. Getters and Setters paradigm. I just cant wrap my head around how to use props to 'pass args' to components and the such.
export default class HelloWorldApp extends Component {
render() {
return (
<View style={{ flex: 1, alignItems: "flex-end" }}>
<CustomButton
text="N"
onPress={() => {
OutputBox.setOutputBox('You head North');
alert("You head North");
}}
/>
<OutputBox></OutputBox>
</View>
);
}
}
class CustomButton extends Component {
render() {
const { text, onPress} = this.props;
return (
<TouchableOpacity style={styles.buttonStyle}
onPress={() => onPress()}
>
<Text style={styles.textStyle}>{text}</Text>
</TouchableOpacity>
);
}
}
class OutputBox extends Component {
constructor( props ) {
super( props );
var displayText = 'Hello Traveller';
}
setOutputBox( newText ){
displayText = newText;
}
render() {
return (
<View style={ styles.outputBox }>
<Text>{this.displayText}</Text>
</View>
);
}
}
I would expect to be able to do something similar to what i have, however i just keep getting a typeError: OutputBox.setOutputBox is not a function. I know this is the wrong paradigm for react-native. I can't seem to wrap my head around doing something like this with props and state.
UPDATE: I no longer get the error typeError: OutputBox.setOutputBox is not a function. Now, the OutputBox just doesn't display anything. How I do I get the <Text/> component of the OutputBox to change and display.
Here is the correct way to do it.
export default class HelloWorldApp extends Component {
constructor( props ) {
super( props );
this.state={
displayText : 'Hello Traveller',
}
}
render() {
return (
<View style={{ flex: 1, alignItems: "flex-end" }}>
<CustomButton
text="N"
onPress={() => {
this.setState({displayText:'You head North'})
}}
/>
<OutputBox text={this.state.displayText}/>
</View>
);
}
}
class CustomButton extends Component {
render() {
const { text, onPress} = this.props;
return (
<TouchableOpacity style={styles.buttonStyle}
onPress={() => onPress()}
>
<Text style={styles.textStyle}>{text}</Text>
</TouchableOpacity>
);
}
}
class OutputBox extends Component {
render() {
return (
<View style={ styles.outputBox }>
<Text>{this.props.displayText}</Text>
</View>
);
}
}
I just removed the OutputBox component and put a <Text> component in there. I realized i didn't need the OutputBox component, since it's only purpose was to display text. This is what i ended up with
export default class HelloWorldApp extends Component {
constructor( props ) {
super( props );
this.state={
displayText : 'Hello Traveller',
}
}
render() {
return (
<View style={{ flex: 1, alignItems: "flex-end" }}>
<CustomButton
text="N"
onPress={() => {
this.setState({displayText:'You head North'})
}}
/>
<Text>{this.state.displayText}</Text>
</View>
);
}
}
class CustomButton extends Component {
render() {
const { text, onPress} = this.props;
return (
<TouchableOpacity style={styles.buttonStyle}
onPress={() => onPress()}
>
<Text style={styles.textStyle}>{text}</Text>
</TouchableOpacity>
);
}
}

How to navigate other component when use bind()?

I use react-navigation to navigate other component.
Now i want to navigate to other component with some params(selectedCity态firstSliderValue态secondSliderValue), but onAccept() function will get the error
TypeError: Cannot read property 'bind' of undefined
When i added the params before, i can navigate to my MovieClostTime component. Why i can not add params ? What should i do ?
Any help would be appreciated. Thanks in advance.
Here is my part of code:
constructor(props) {
super(props);
this.state = {
showModal: false,
selectedCity: 'Keelung',
firstSliderValue: 18,
secondSliderValue: 21
};
}
// it will close <Confirm /> and navigate to MovieCloseTime component
onAccept() {
this.setState({ showModal: !this.state.showModal });
const { selectedCity, firstSliderValue, secondSliderValue } = this.state;
console.log(selectedCity); // Keelung
console.log(firstSliderValue); // 18
console.log(secondSliderValue); // 21
this.props.navigation.navigate('MovieCloseTime', {
selectedCity,
firstSliderValue,
secondSliderValue
});
}
// close the Confirm
onDecline() {
this.setState({ showModal: false });
}
render() {
if (!this.state.isReady) {
return <Expo.AppLoading />;
}
const movies = this.state.movies;
console.log('render FirestScrren');
return (
<View style={{ flex: 1 }}>
{/* Other View */}
{/* <Confirm /> is react-native <Modal />*/}
<Confirm
visible={this.state.showModal}
onAccept={this.onAccept.bind(this)}
onDecline={this.onDecline.bind(this)}
onChangeValues={this.onChangeValues}
>
</Confirm>
</View>
);
}
My Confirm.js
import React from 'react';
import { Text, View, Modal } from 'react-native';
import { DropDownMenu } from '#shoutem/ui';
import TestConfirm from './TestConfirm';
import { CardSection } from './CardSection';
import { Button } from './Button';
import { ConfirmButton } from './ConfirmButton';
const Confirm = ({ children, visible, onAccept, onDecline, onChangeValues }) => {
const { containerStyle, textStyle, cardSectionStyle } = styles;
return (
<Modal
visible={visible}
transparent
animationType="slide"
onRequestClose={() => {}}
>
<View style={containerStyle}>
<CardSection style={cardSectionStyle}>
<TestConfirm onChangeValues={onChangeValues} />
{/* <Text style={textStyle}>
{children}
</Text> */}
</CardSection>
<CardSection>
<ConfirmButton onPress={onAccept}>Yes</ConfirmButton>
<ConfirmButton onPress={onDecline}>No</ConfirmButton>
</CardSection>
</View>
</Modal>
);
};
const styles = {
// some style
};
export { Confirm };

In React-native, how to handle checkbox in Listview?

In my react-native app, I am trying to show my contact details with checkboxes for selecting.
Here is my code:
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData, sectionID, rowID) => (
<TouchableHighlight onPress={() => this.goRideDetails(rowData)}>
<Text style={styles.rideHeader}>{rowData.name} </Text>
<CheckBox
checked={this.state.checked}
onCheckBoxPressed={() =>
this.setState({ checked: !this.state.checked })
}
/>
</TouchableHighlight>
)}
/>
In my view checkbox is displaying on every row, but not working.
Any one can help me. Thanks in advance.
You can easily do this with component separation. Please, take a look here:
export default class ContactList extends Component {
static propTypes = {
contacts: React.PropTypes.array,
}
static defaultProps = {
contacts: [],
}
constructor(){
super();
this._renderRow = this._renderRow.bind(this);
}
_renderRow(rowData,sectionID,rowID) {
return <Contact info={ rowData } />;
}
render() {
return (
<ListView
dataSource={ this.props.contacts }
renderRow={ this._renderRow }
/>
);
}
}
export class ContactList extends Component {
static propTypes = {
info: React.PropTypes.object.isRequired,
}
constructor(){
super();
this.goRideDetails = this.goRideDetails.bind(this);
this.setChecked = this.setChecked.bind(this);
}
goRideDetails() {
//your logic here
}
setChecked() {
this.props.info.checked = !this.props.info.checked; //will be much better to do it with redux and action creators
}
render() {
return (
<TouchableHighlight onPress={ this.goRideDetails }>
<Text style={ styles.rideHeader }>{this.props.info.name} </Text>
<CheckBox checked={ this.props.info.checked } onCheckBoxPressed={ this.setChecked } />
</TouchableHighlight>
);
}
}
After that you can simply call:
<ContactList contacts={this.state.dataSource} />
in your jsx and voila.
Important note: Do not use array functions inside your jsx code blocks.
Important note 2: Try to start using redux or flux for storing state of your application. It will be provide much better code design.
Hope, it will help.
import React , {Component} from 'react'
import {
Text,
View,
ListView,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native'
import CheckBox from 'react-native-checkbox'
var Folder = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
var folder = '' ////// all the new folder
var check_folder = [] ////// all the check box conditions
class ApproveContent extends Component {
///////// all the upper thing that are global variable for this script is has same value as that of the state the only reason we are using this because of the layout update //////////
state={
folder:[],
data:[],
check:[]/////// this need to do just to upadte the layout of the check box
}
render(){
return(
<View style = {{flex:1,backgroundColor:'white',alignItems:'center'}}>
<ListView
dataSource={Folder.cloneWithRows(this.state.folder)}
renderRow={(rowData,rowID,sectionID) => <View style = {{ alignItems: 'center',margin:5}}>
<TouchableOpacity style = {{width:Dimension.ScreenWidth/1.2,height:Dimension.ScreenHeight/6,flexDirection: 'row',alignItems:'center'}}
onPress={() => {}}>
<CheckBox
label=''
labelBefore={false}
checked={this.state.check[sectionID]}
checkboxStyle = {{marginLeft: 20}}
onChange={(checked) => {
this.setState({
check:!this.state.check
})
if(check_folder[sectionID] == false){
check_folder[sectionID] = true
this.setState({
check:check_folder// has to do this because we cant change the single element in the array
})
}else{
check_folder[sectionID] = false
this.setState({
check:check_folder// has to do this because we cant change the single element in the array
})
}
console.log(check_folder)a
}}
/>
</TouchableOpacity>
</View>
}
/>
</View>
)}
}
export default ApproveContent
const style = StyleSheet.create({
TextStyle:{
fontFamily: 'Roboto-Bold',
fontSize:15,
},
approveButton: {
bottom:0,
left:0,
alignItems: 'center',
}
})

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