I am using react-native and i have a NavigationDrawer.When i press ListItem i change the page. What i want to do now is to change only half of page's view depending on what user presses.
export default class Some extends Component {
render() {
return (
<View style={styles.View1}>
<View style={styles.hed}>
<View style={styles.imageview}>
<Image style={styles.img} source={require('../images/logo3.png')} />
</View>
</View>
<View style={styles.View2}>
<Page2/>
</View>
</View>
);
}
}
So what i want is depending onPress change to Page 3, Page4.. BUT the first view to stay constant.
You can switch the pages with a logic like this:
export default class Some extends Component {
constructor() {
// You define the first page seen
this.state = { currentPage: 1 };
}
onPress = () => {
// Here your logic to choose the page with:
this.setState({ currentPage: ... });
}
render() {
// All of your pages
const pages = {
1: <Page1 />,
2: <Page2 />,
3: <Page3 />,
};
const { currentPage } = this.state;
return (
<View style={styles.View1}>
<View style={styles.hed}>
<View style={styles.imageview}>
<Image style={styles.img} source={require('../images/logo3.png')} />
</View>
</View>
<View style={styles.View2}>
{/* Display the selected page */}
{pages[currentPage]}
</View>
</View>
);
}
}
Related
I am trying to show or print the duration (timer) when the button start is pressed, but nothing is showing after pressing start. I tried doing Button instead of TouchableOpacity, but still, nothing changed.
class Timer extends Component {
constructor(props){
super(props)
this.state = {
count: 0
}
}
render () {
const {count} = this.state
return (
<ScrollView>
<SafeAreaView style={styles.container}>
<View style={styles.textInputContainer}>
<Text style={styles.txtHello}>Press start when ready</Text>
<View style={styles.sep}>
</View>
<TouchableOpacity style={styles.button}
onPress={ () =>
<View style={styles.textInputContainer}>
<Text>
<h2> Duration: {count}</h2>
</Text>
</View>
}
>
<Text>start</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
</ScrollView>
)
}
componentDidMount(){
this.myInterval = setInterval(()=>{
this.setState({
count: this.state.count + 1
})
}, 1000)
}
}
I don't think this is a right way to do it in React. What you would like to do is set a isVisible state, change it with your onPress props in Button/TouchableOpacity and finally conditionally show the view you want to display based on that isVisible variable. Something like this:
class Timer extends Component {
constructor(props){
super(props)
this.state = {
isVisisble:false;
}
}
render(){
return(
<View>
<TouchableOpacity
onPress={ () => this.setState((prevState)=>{isVisible:!prevState.isVisible})}
>
<Text>start</Text>
</TouchableOpacity>
{this.state.isVisible && <View></View>} <- Conditional View here
</View>
)}
I am using React Native FlatList and React Native Modal.
Upon clicking on the item from the FlatList, I want to view 1 Modal only (containing the details of the item selected).
However, if there are 4 items in the FlatList, selecting 1 item causes
all 4 modals to pop up.
Is there anyway I can display only 1 modal for 1 selected item in the FlatList instead of multiple modal?
Code Snippet below (some lines of code were removed as it's not needed):
constructor(props) {
super(props);
this.state = {
dataSource: [],
isLoading: true,
modalVisible: false,
}
}
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
viewModal(item, price) {
const { modalVisible } = this.state;
return (
<Modal
statusBarTranslucent={true}
animationType={"slide"}
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View>
<View>
<View>
<Text>
Appointment Start Time:
</Text>
<Text>
{moment(item.time_start).format('h:mm a')}
</Text>
</View>
<View>
<Text>
Appointment End Time:
</Text>
<Text>
{moment(item.end_start).format('h:mm a')}
</Text>
</View>
<View style={styles.row}>
<Text>
Total:
</Text>
<Text>
{price}
</Text>
</View>
<View>
<View>
<Button
mode="outlined"
onPress={() => {
this.setModalVisible(!modalVisible);
}}
>
{'Cancel'}
</Button>
</View>
<View>
<Button
mode="contained"
onPress={() => {
this.setModalVisible(!modalVisible);
}}
>
{'Accept'}
</Button>
</View>
</View>
</View>
</View>
</Modal>
);
}
viewFreelancerTime() {
return (
<View>
<FlatList
renderItem={({ item }) => {
let totalPrice = (parseFloat(item.service_price) + parseFloat(item.service_deposit)).toFixed(2);
return (
<Container>
{this.viewModal(item, totalPrice)}
<TouchableNativeFeedback
onPress={() => {
this.setModalVisible(true);
}}
>
<View>
<View>
<Text>
{moment(item.time_start).format('h:mm a')}
</Text>
</View>
<View>
<Text>
{totalPrice}
</Text>
</View>
</View>
</TouchableNativeFeedback>
</Container>
);
}}
/>
</View>
);
}
render() {
return (
<>
<View style={{ flex: 1 }}>
{this.viewFreelancerTime()}
</View>
</>
);
};
The poblem is that you are rendering the modal in the renderItem method, so every time you select an item, the modal will open in each rendered item.
To solve that you will have to render a custom Modal component with an absolute position at the same level of your FlatList, and pass the selected item information as props.
UPDATE
Just something like this:
import React, {useState} from "react";
import { Modal } from "react-native";
export default function MyFlatList(props) {
const [selectedItem, setSelectedItem] = useState(null);
const handleOnSelectItem = (item) => {
setSelectedItem(item);
};
const handleOnCloseModal = () => {
setSelectedItem(null);
};
renderItem = ({ item }) => {
return (
<Container>
<TouchableNativeFeedback onPress={() => handleOnSelectItem(item)}>
<View>
<View>
<Text>{moment(item.time_start).format("h:mm a")}</Text>
</View>
<View>
<Text>{totalPrice}</Text>
</View>
</View>
</TouchableNativeFeedback>
</Container>
);
};
return (
<View>
<FlatList renderItem={this.renderItem} />
<CustomModal isVisible={selectedItem} selectedItem={selectedItem} onClose={handleOnCloseModal} />
</View>
);
}
export function CustomModal(props) {
const { isVisible, item, onClose, /*...*/ } = props;
// Play with the item data
let totalPrice = (
parseFloat(item.servicePrice) + parseFloat(item.serviceDeposit)
).toFixed(2);
return <Modal visible={isVisible} onRequestClose={onClose}>{/*...*/}</Modal>; // Render things inside the data
}
I suggest you to do a pagination and play with FlatList native props if you are going to implement an infinite scroll.
Pd: to reduce re-renders because of state updates, I am reusing the selectedItem state, so if it is not null then the modal will be visible
Hey there so i'm new to react native and javascript and currently i'm learning to make a custom radio button with images it looks like this my custom radio button in this page user is going to pick one button from the list, and i want to make it when the page first render it will show one pressed button and user is only allowed to pick one button. Can anyone tell me how to figure this out? Thanks in advance
here are my codes
RadioButton.js
export default class RadioButton extends Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.currentSelection === this.props.value,
}
}
button() {
var imgSource = this.state.selected? this.props.normalImg : this.props.selectedImg;
return (
<Image
source={ imgSource }
/>
);
}
render() {
let activeButton = this.props.activeStyle ? this.props.activeStyle : styles.activeButton;
return (
<View style={[styles.container, this.props.containerStyle, this.state.selected || this.props.normalImg ? activeButton : inactiveButton]}>
<TouchableOpacity onPress={() => {
this.setState({ selected: !this.state.selected });
}}>
{
this.button()
}
</TouchableOpacity>
</View>
);
}
}
ActivityLog.js
class ActivityLog extends Component {
constructor(props){
super(props);
}
render() {
return (
<View style={styles.innerContainer}>
<Text style={styles.dialogText}>{`Log my activity at ${time} as...`}</Text>
<View style={styles.buttonContainer}>
<RadioButton selectedImg={img.activity.breakA} normalImg={img.activity.break} containerStyle={{marginHorizontal: normalize(10)}}/>
<RadioButton selectedImg={img.activity.meetingA} normalImg={img.activity.meeting} containerStyle={{marginHorizontal: normalize(10)}}/>
</View>
<View style={styles.buttonContainer}>
<RadioButton selectedImg={img.activity.otwA} normalImg={img.activity.otw} containerStyle={{marginHorizontal: normalize(10)}}/>
<RadioButton selectedImg={img.activity.officeA} normalImg={img.activity.office} containerStyle={{marginHorizontal: normalize(10)}}/>
</View>
);
}
}
Extract the activeStatus to ActivityLog so as to track which button is selected,right now you are maintaing a state for every button as a local state.So it is difficult to know other components to know about the button's active status.
Here is a generic implementation for rough idea.
const Child=(props)=>{
<TouchableOpacity onPress={props.handlePress}>
<Text style={[baseStyle,active && activeStyle]}>{props.title}</Text>
</TouchableOpacity>
}
class Parent extends React.Component{
state={
selectedChild:''
}
changeSelection=(sometitle)=>{
this.setState({
selectedChild:sometitle
})
}
render(){
return(
<View>
<Child handlePress={()=>this.changeSelection('1')} active={this.state.selectedChild==='1'}/>
<Child handlePress={()=>this.changeSelection('2')} active={this.state.selectedChild==='2'}/>
<Child handlePress={()=>this.changeSelection('3')} active={this.state.selectedChild==='3'}/>
<Child handlePress={()=>this.changeSelection('4')} active={this.state.selectedChild==='4'}/>
</View>
)
}
}
Expo demo Link
As an iOS dev I'm struggling a bit with react native.
I have two components inside different classes:
Component A is a view with a TextInput
class A extends Component<Props>{
state = {
textFieldValue: ""
};
render() {
return (
<View>
<TextInput placeholder={this.props.placeholderText}
ref={textField => {
this.textField = textField;
}}
value={this.state.textFieldValue}
onChange={e => this.setState({ textFieldValue: e.target.value})}/>
</View>
);}
}
Component B uses A in it's view
class B extends Component<Props>{
render() {
return (
<View>
<A placeholder={"test"}/>
<TouchableOpacity onPress={() => {
//show text of input A here
}}>
<View>
<Text>{text}</Text>
</View>
</TouchableOpacity>
</View>
);}
}
How can I access the value/state with the value of the TextInput in A from B to show it on the button press?
Try this on Class B
class B extends Component<Props>{
render() {
return (
<View>
<A placeholder={"test"} ref={c => this.textRef = c}/>
<TouchableOpacity onPress={() => {
//show text of input A here
alert(this.textRef.state.textFieldValue)
}}>
<View>
<Text>{text}</Text>
</View>
</TouchableOpacity>
</View>
);}
}
Access reference of class A through ref props, then get its own state.
I am new to react native how can i send data from one screen to another screen using props in android not for ios my code is as below
Home.js
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
qwerty:{
data:[],
},
};
}
goPressed(navigate){
navigate("Product");
}
render() {
const { navigate } = this.props.navigation;
contents = this.state.qwerty.data.map((item) => {
return (
<View key={item.p1.id}>
<View>
<Text>{item.p1.content}</Text>
</View>
<View>
<TouchableHighlight onPress={() => this.goPressed(navigate)}>
<Text>
Go
</Text>
</TouchableHighlight>
</View>
</View>
);
});
return (
<ScrollView style={styles.container}>
{contents}
</ScrollView>
);
}
}
export default Home;
this is my home.js , I want pass data i.e {item.p1.content} to another screen i.e product.js so how can i do it what modification should i do?
Product.js
export default class Products extends Component {
static navigationOptions = {
title: "Products",
};
render() {
return (
<View style={{ flex: 1 }}>
<Text>{item.p1.content}</Text>
</View>
);
}
}
Send data to other screen
this.props.navigation.navigate('Your Screen Name' , { YourParamsName: "Foo"});
Receive data from other screen
this.props.navigation.state.params.YourParamsName
One method is to simply pass the date you are storing in 'qwerty' as a props to the next scene.
In Home.js you can modify your goPressed method to be something like...
goPressed(navigate){
navigate("Product", {passedData: this.state.qwerty.item.p1.content});
}
Then in Product.js you will need to modify the code to
render() {
return (
<View style={{ flex: 1 }}>
<Text>{this.props.passedData}</Text>
</View>
);
}