React-Native: Access TextField value in another class - javascript

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.

Related

React native js. nothing shows when pressing the start button

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>
)}

React Native: FlatList Opens Modal for all Items Instead of Selected Item

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

Get value from a TextInput component in react native

Dynamically generate a TextInput when you press a button but I can’t get the value that the user digits,try to use states but I can’t because it’s not with the other general textInputs but it’s imported as Field.
try to create a state in the component file and move it to the general view and print it to see if it works and not...is there any way to bring this state?
general view:
import Campo from './campoInput';
constructor(props){
super(props);
this.state={
Cbusto:"",
Ccintura:"",
Ccadera:"",
valueArray: []
};
this.addNewEle = false;
}
agregarCampo=()=>{
this.addNewEle = true;
const newlyAddedValue = { text: 'prueba'};
this.setState({
valueArray: [...this.state.valueArray, newlyAddedValue]
});
}
render(){
return(
------Here are the normal textInput-----
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele} />;
})}
</View>
<View style={styles.flex}>
<View style={styles.ButtonAdd}>
<Button
title="Add input"
color="#B13682"
onPress={this.agregarCampo}
></Button>
</View>
)
}
Component:
constructor(props){
super(props);
this.state={
info:""
};
}
render(){
return(
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={(text) => this.setState({info:text})}></TextInput>
</View>
</View>
)
}
can be solved by adding the onChangeText event to the Field component in the overview and in the same way in the TextInput of the component being imported, using props status
General view:
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele}
onChangeText={(text) => this.setState({ info: text })}
/>;
})}
</View>
Component
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={this.props.onChangeText}></TextInput>
</View>
</View>

Custom Radio Button React Native

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

onPress change fragment view

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>
);
}
}

Categories