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

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.

Related

React Native: Back Button Closes Modal

I'm trying to make a text open a modal when the user pressed on it and closes when they press on the back button. The modal does not open when the user clicks on the text. I tried following the solution from other questions but it doesn't work and their modal are not in a separate component.
Login.js
const [modalOpen, setModalOpen] = useState(false);
return (
<CustomScrollView>
<ForgotPassword open={modalOpen}/> //Modal
<ForgotPasswordText onPress={() => setModalOpen(true)}>Forgot Password?</ForgotPasswordText>
</CustomScrollView>
);
ForgotPassword.js
const ForgotPassword = ({open}) => {
const [invisible, setInvisible] = useState({open});
return (
<Modal
statusBarTranslucent
transparent= {true}
visible={invisible}
animationType="fade"
onRequestClose={() => {setInvisible(!open);}}>
<CenteredModal>
<ModalView>
<ForgotPasswordTitle>Forgot Password</ForgotPasswordTitle>
</ModalView>
</CenteredModal>
</Modal>
);
}
Both components are mounted already. If you are changing the modalOpen state in your root component, it would not trigger the modal to be opened in the ForgotPassword component in the way it is implemented.
One solution would be to pass the modalOpen prop right away and using it in your Modal component for the visible prop. But you would need to pass your setModalOpen function from your Login component to remain the state, too.
const [modalOpen, setModalOpen] = useState(false);
return (
<CustomScrollView>
<ForgotPassword open={modalOpen} setOpen={setModalOpen} /> //Modal
<ForgotPasswordText onPress={() => setModalOpen(true)}>Forgot Password?</ForgotPasswordText>
</CustomScrollView>
);
const ForgotPassword = ({open, setOpen}) => (
<Modal
statusBarTranslucent
transparent={true}
visible={open}
animationType="fade"
onRequestClose={() => setOpen(!open)}>
<CenteredModal>
<ModalView>
<ForgotPasswordTitle>Forgot Password</ForgotPasswordTitle>
</ModalView>
</CenteredModal>
</Modal>
);
Find it working here:
https://codesandbox.io/s/broken-night-lu8e96

react native textinput lost focus after 1 char type

I have this problem with ios but not with android. It only disturb the add task input the task edit and the list name edit. The input addList(It's the one with "What to do?" on the draw) in the header works fine.
UI drawing
Achitecture of components
I console log my component and I can see it rerender everytime I add a letter in the input field.
I checked on google and follow this:(can we link other website here?) https://www.codegrepper.com/code-examples/javascript/react+native+textinput+lost+focus+after+charter+type
Tried the the first solution with onBlurr and onFocus.
I tried to make a TextInput component for add task.
I even try with my component addList but it didn't solve the problem.
Anyone have faced this problem before? Is there anyway to by pass this?
My code without the import/style look like this:
const TaskList: FunctionComponent<TasksListProps> = ({
addTask,
deleteTask,
toggleTask,
editTaskName,
...props
}) => {
console.log('props', props);
const [nameOfTask, setNameOfTask] = useState('');
console.log('name', nameOfTask);
const textHandler = (enteredName: string) => {
setNameOfTask(enteredName);
};
const handleSubmitTask = () => {
if (nameOfTask === '') {
return;
}
addTask(props.listId, nameOfTask);
setNameOfTask('');
};
return (
<View style={styles.tasksListContainer}>
{props.tasks.map(task => (
<SingleTask
key={task.id}
task={task}
listId={props.listId}
deleteTask={deleteTask}
toggleTask={toggleTask}
editTaskName={editTaskName}
/>
))}
<View style={styles.taskInputContainer}>
<TextInput
style={styles.tasksTextInput}
value={nameOfTask}
onChangeText={textHandler}
placeholder="Write a task to do"
/>
<TouchableOpacity onPress={handleSubmitTask}>
<Image source={require('./Img/add-button.png')} />
</TouchableOpacity>
</View>
</View>
);
};
You can create a HOC and wrap your screen width DismissKeyboard
import { Keyboard } from 'react-native';
const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
{children}
</TouchableWithoutFeedback>
);
That because Re render.
Try to make the input with the main component of the page to test it.
Then check where the error with re-render

creating component in onPress event

I'm trying to build an android app using functional react-native and expo.
I want to know to create new components inside other components when events are triggered.
What I'm trying to do is the following
The code I wrote is below:
<View>
<TouchableOpacity style = {styles.container} onPress = {() => {return (
<TouchabeOpacity>
<Text> Hello World </Text>
</TouchabeOpacity> ) }}
</ToucchabeOpacity>
</View>
I want when pressing the first touchableopacity another one would be created and displayed.
Any solutions ?
You need to do something like:
import {NewComponent} from './components/NewComponent';
....
const[displayNewComponent, setDisplayNewComponent] = useState(false)
...
<View>
<TouchableOpacity style = {styles.container} onPress={() => setDisplayNewComponent(true)}
{ displayNewComponent && <NewComponent /> }
</ToucchabeOpacity>
</View>
export const NewComponent = () => {
return (
<TouchabeOpacity>
<Text> Hello World </Text>
</TouchabeOpacity>
)

Creating Modal Object need help dealing with isVisible state

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.

FlatList's renderItem doesn't recognise "this" keyword

So, I recently started making FlatList a recurring thing in the app I'm working on. I am right now working on a screen that gives a list of requests and is updated once one is accepted, which is done by pressing a button. There's a method called getNewRequests I am using to update the requests, but it can't seem to be called by the flatline, as it only returns the error TypeError: _this3 is undefined.
I really need that method to work, because I need to update the state of that screen, and trying to type the whole method there only returns the same error. In that context, this always returns undefined.
render(){
return(
<View style={GenericStyles.styles.genericContainer}>
<Text> REQUEST SCREEN </Text>
<FlatList
data={this.state.requestList}
renderItem={this.renderItem}
keyExtractor={item => item.id}
/>
<Button title="Voltar" color="cyan" onPress={() => this.props.navigation.goBack()}/>
</View>
);
}
renderItem({item}){
return(
<Card
containerStyle={{flex: 1, width: 200}}
title={item.Username}>
<Button color="blue" title="Accept" onPress={() => RequestService.allowRequest(item.id, (response) => {
let rsp = JSON.parse(response);
if(rsp.success){
this.getNewRequests();
}
})}/>
</Card>
);
}
You need to either bind the function in your constructor (or wherever you want) doing:
constructor(props){
super(props)
this.renderItem.bind(this)
}
or use arrow function:
renderItem = ({item}) => {
//your function
}
Doing this will give the function access to the this of the current component.