Creating Modal Object need help dealing with isVisible state - react-native

I am currently trying to create a Modal object using react-native-modal like this
const ModalExample = (props) => {
return (
<Modal isVisible={props.isVisible}>
<Text>Hello!</Text>
<Button title="Hide modal" onPress={this.setModalVisibility} />
</Modal>
)
}
The problem is that the onPress is supposed to change the state from true to false but doesn't have access to the state within the class.
Here is the button that initializes the modal and how i'm calling the object:
<Button title="Show modal" onPress={this.setModalVisibility} />
<ModalExample isVisible={this.state.modalVisible}/>
and just incase here is my setModalVisibility that is within the class
setModalVisibility = () =>{
this.setState({modalVisible: !this.state.modalVisible})
}
Thanks for any help

You need to pass the function as well,
<ModalExample isVisible={this.state.modalVisible} setModalVisibility={this.setModalVisibility}/>
Call that function in modal,
const ModalExample = (props) => {
return (
<Modal isVisible={props.isVisible}>
<Text>Hello!</Text>
<Button title="Hide modal" onPress={props.setModalVisibility} />
</Modal>
)
}
Note: You don't have access to this in functional component.

Related

How to make alert on click of button

Is there a way to make Alert on click not using the alert method but Alert tag. Currently I tried using usestate but didn’t work
Hard to know what your problem is without seeing code but this is the general approach to show tag based components. Don't forget to revert the state value on dismissal.
const [showAlert, setShowAlert ] = useState(false);
return (
<>
{showAlert ?
<Alert {...otherPropsHere} />
: <View/> }
<Button title="Press Me" onPress={() => {setShowAlert(true)} />
</>
)
If the tag has a 'visible' prop then it would be more like this
const [showAlert, setShowAlert ] = useState(false);
return (
<>
<Alert visible={showAlert} {...otherPropsHere} />
<Button title="Press Me" onPress={() => {setShowAlert(true)} />
</>
)
If you need multiple alerts you could:
const [showAlertOne, setShowAlertOne ] = useState(false);
return (
<>
{showAlertOne ?
<Alert {...otherPropsHere} />
: <View/> }
{showAlertTwo ?
<Alert {...otherPropsHere} />
: <View/> }
<Button title="Show Alert One" onPress={() => {setShowAlertOne(true)} />
<Button title="Show Alert Two" onPress={() => {setShowAlertTwo(true)} />
</>
)
This isn’t the best way to do it but I think this should clear up the concept of what you are trying to do. A better way - if the alerts don’t show at the same time - is to have a single state object in which you store which alert you want to show. These could be an ENUM too to add a little safety.
This is the (partially) typed example with an enum and a wrapped component.
const myApp = () => {
enum AlertType = { One, Two, Three }
const [visibleAlert, setVisibleAlert ] = useState<AlertType | null>(null);
const VisibleAlert = (alertType:AlertType) => {
switch (visibleAlert) {
case AlertType.One:
return <Alert {otherPropsHere} />
break;
case AlertType.One:
return <Alert {otherPropsHere} />
break;
default:
return <View/>
break;
}
}>
return (
<>
<VisibleAlert alertType={visibleAlert} />
<Button title="Show Alert One" onPress={() => {setVisibleAlert(AlertType.One)} />
<Button title="Show Alert Two" onPress={() => {setVisibleAlert(AlertType.Two)} />
</>
)
}
Wrapping the modal in a component with its own state might be a good approach but let’s see what your issue is for sure first.

How to change state of react hook inside other component

Senario
I have a dialog, it look something like this, it have hook for showing this dialog, called showDialog , and dialog have a button with Onpress method
export default function DialogTesting(show: boolean) {
const [showDialog, doShow] = useState(show)
return (
<View>
{/* <Button
title="click"
onPress={() => {
setShow(true)
}}
>
<Text>Show dialog</Text>
</Button> */}
<Dialog
visible={showDialog}
title="Record New Progress"
style={DIALOG}
onClose={() => {
doShow(false)
}}
>
And a main sceen , it also have hook to show dialog, called show,
export const MedicalRecord = memo(function MedicalRecord() {
// const onPressViewAll = useCallback(() => {}, [])
const [show, setShow] = useState(false)
function hanndleDialog() {
setShow(!show)
}
return (
<SummaryViewContainer
count={5}
title={"dashboardScreen.medicalRecords.title"}
onPress={() => {
hanndleDialog()
}}
>
<View>
{show && (
<ProgressDialog
show={show}
callback={() => {
hanndleDialog()
}}
/>
)}
<RecordItem />
<RecordItem />
<RecordItem />
</View>
</SummaryViewContainer>
)
})
Problem
When i click the button in main screen, change hook show to true to show dialog, and use this hook state in dialog to set show in dialog to true to show that dialog, and in dialog, when i click button to close dialog, it disappear, but problem is, the state of show in main screen remain true, so i have to press twice to show dialog again
Question
How can i change hook status in main screen, or how can i press close button in dialog, the show hook in main screen return false, i tried to change state of mainscreen in dialog but it won't work
Here is a short video of problem
https://streamable.com/9mm26t
You should maintain just one copy of your state in the parent component itself. Then pass "show" and "setShow" as props to the child component.
Parent Component:
export const MedicalRecord = memo(function MedicalRecord() {
// const onPressViewAll = useCallback(() => {}, [])
const [show, setShow] = useState(false)
function hanndleDialog() {
setShow(!show)
}
return (
<SummaryViewContainer
count={5}
title={"dashboardScreen.medicalRecords.title"}
onPress={() => {
hanndleDialog()
}}
>
<View>
{show && (
<ProgressDialog
show={show}
setShow = {setShow}
/>
)}
<RecordItem />
<RecordItem />
<RecordItem />
</View>
</SummaryViewContainer>
)
})
Dialog Component:
export default function DialogTesting({show, setShow}) {
return (
<View>
{/* <Button
title="click"
onPress={() => {
setShow(true)
}}>
<Text>Show dialog</Text>
</Button> */}
<Dialog
visible={show}
title="Record New Progress"
style={DIALOG}
onClose={() => {
setShow(false)
}}
>
</View>
)
}
It looks like you have 2 versions of local state at each component. You need to keep 1 version of "show" at the top most parent where you care to control this variable and then pass it down as a prop to your child components. Then on your child components you need to expose a callback that the parent will pass down and the child will call to trigger what occurs when the button is clicked in the child component.

How to show component when a function is called in ReactNative (Like Alert.alert())

I would to create a custom component to be rendered when a function is called in ReactNative. Is like a alert() component. In this case i don't want use a modal, a want to make a component that can showed in screen when a function is called. Someone have any ideia about how i can made this?
I want to make this:
const Example = () => {
return(
<View>
<Button title="Show Modal" onPress={showModal}/>
</View>
)
}
I can't make this:
const Example = () => {
const [isVisible, setIsVisible] = useState(false);
return(
<View>
<Modal visible={isVisible}>
<Text>Awesome code here ...</Text>
</Modal>
<Button title="Show Modal" onPress={() => {setIsVisible(true)}}/>
</View>
)
}
What i want to do is show the component whitout put her jsx in my return. I need to call a function, when this function is called my componnent is showed in screen. The logic is same of Alert.alert() function.

Ternary operator in react-native

I need to show a component only if a variable is true, basically I'm going to create two buttons, one to set variable to false and another to true. I'm trying to use the * ngIf idea of the Angular. I need something like this:
render() {
return (
<View>
<Button
title="Click me"
onPress={ () => { this.loading = true } }
/>
{this.loading ? <Modal /> : null}
</View>
);
}
It seems you are new to React, in react state and handlers are either held in state or passed has props.
you can achieve this having a component state like show , have click handlers which set the State then in render you can check this.state.show and take decision to either show the component or not
setShow = () = >{
this.setstate({show : true});
}
render() {
return (
<View>
<Button
title="Click me"
onPress={this.setShow}
/>
{this.state.show ? <Modal /> : null}
</View>
);
}

Passing values dynamically to child component react native

App.js
render() {
return (
<View style={{ flex: 1, marginTop: 20 }}>
<Button
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
onPress={() => {
(this.state.dadda = '2017-09-07');
}}
/>
<EventCalendar
eventTapped={this._eventTapped.bind(this)}
events={this.state.events}
width={width}
initDate={this.state.dadda}
scrollToFirst={false}
/>
</View>
); }
This is my parent component ,I want to pass initDate to event calendar component,I want to update the date when the button is pressed?
You should not mutate the state by assigning value to the state variable directly but instead use setState to acheive that.
<Button
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
onPress={() => this.setState({dadda: '2017-09-07'})}
/>
The way you are setting dadaa into the state is not correct, use this.setState function instead, have a look at the doc.
Change your onPress handler to
...
< Button
title = "Learn More"
color = "#841584"
accessibilityLabel = "Learn more about this purple button"
onPress = {
() => {
this.setState({
dadda:'2017-09-07'
});
}
}
/>
...
Also, don't declare the function inside render, rather keep it at the class level like
onPressHandler = () => {
this.setState({
dadaa: 'aaaa'
});
}
render() {
return (
...
<
Button
...
onPress = {this.onPressHandler}
...
/>
...
);
}
Hope this will help!