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
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>
)}
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>
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.
So basically I have a Screen in my app that has a Button in it and this button should open a Modal that is also a selfmade component in the same screen js file.
I am setting the state visible in the screen and the button has an onPress handler that toggles the visible state (false/true).
I dont know how to display my own modalComponent when the button is clicked.
btw using react-native-modal
Own modal component:
class PhasenModal extends Component {
render() {
return (
<View>
<Modal isVisible={this.props.visible}>
<View style={{ flex: 1 }}>
<Text>I am a modal</Text>
</View>
</Modal>
</View>
);
}
}
In my ScreenView :
<Button
buttonStyle={styles.phaseButton}
title="Choose"
onPress={() => this.phasenModalHandler()}
/>
The onPress fnct:
phasenModalHandler() {
this.setState({ visible: !this.state.visible });
if (this.state.visible) {
return <PhasenModal visible={this.state.visible} />;
} else {
return;
}
}
I expect the button to show the Modal but it doesnt show anything ,
the state gets toggled correctly tho it switched from false to true.
I guess my onPress fctn is wrong becaus I dont know how to render the component.
Thank you in advance.
What you return from your event handler will not be rendered, so you could instead use the visible value in your state to conditionally render the PhasenModal component.
class ScreenView extends Component {
state = {
visible: false
};
phasenModalHandler = () => {
this.setState(({ visible }) => ({ visible: !visible }));
};
render() {
return (
<>
<Button
buttonStyle={styles.phaseButton}
title="Choose"
onPress={this.phasenModalHandler}
/>
{this.state.visible && <PhasenModal />}
</>
);
}
}
class PhasenModal extends Component {
render() {
return (
<View>
<Modal isVisible>
<View style={{ flex: 1 }}>
<Text>I am a modal</Text>
</View>
</Modal>
</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>
);
}
}