Focus text input on TouchableHighlight clicked - javascript

I have a class that I want the text input inside it to focus on the parent being selected.
class ListItem extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
editable: this.props.item.editable,
value: this.props.item.value,
heading: this.props.item.heading,
item: this.props.item.item,
}
}
_onPress = () => {
this.setState({ editable: true});
this.props.onPressItem(this.props.index, this.props, this.state);
}
_onSearchTextChanged = (event) => {
this.setState({ value: event.nativeEvent.text });
};
_handleSaveEvent = (e) => {
this.setState({ editable: false });
alert('works');
//Add in saving item
}
render() {
var editable = this.state.editable;
var heading = this.state.heading;
var value = this.state.value;
return (
<TouchableHighlight onPress={this._onPress} underlayColor='#dddddd'>
<View>
<View style={styles.rowContainer}>
<View style={styles.textContainer}>
<Text style={styles.title}>{heading}: </Text>
{this.state.editable?
<TextInput
style={styles.searchInput}
value={value.toString()}
onChange={this._onSearchTextChanged}
keyboardType="default"
returnKeyType="done"
onSubmitEditing={this._handleSaveEvent}/>
:
<Text style={styles.price}>{value}</Text>
}
{}
</View>
</View>
<View style={styles.separator}/>
</View>
</TouchableHighlight>
);
}
}
Ive tried adding
autoFocus={true}
Ive also tried adding
ref={this.props.index}
But when I try to focus that it tells me its not defined (this.refs[this.props.index].focus();)
I would like it to be focused when the 'editable' state is enabled, I am not sure why this seems so hard. My background is more in C#, Angular 2+ etc so maybe its just how react is structured is throwing me

on the onPress event of TouchableHighlight setState editable: true and set autoFocus={this.state.editable} in TextInput..it will work
<TextInput
style={styles.searchInput}
value={value.toString()}
onChange={this._onSearchTextChanged}
keyboardType="default"
autoFocus={this.state.editable}
returnKeyType="done"
onSubmitEditing={this._handleSaveEvent}
/>

You can try this. Provide ref as a function in <TextInput /> like this:
<TextInput
ref ={ref => this.inputText = ref}
style={styles.searchInput}
keyboardType="default"
placeholder="Type anything"
returnKeyType="done"/>
And now on <Button />onPress, focus the <TextInput /> like this:
<TouchableHighlight onPress={() => this.inputText.focus()}>
<Text>Click</Text>
</TouchableHightlight>
This should work. Let me know if there is any problem.

Related

How to pass and execute functions as props in class Component in React Native?

I'm a beginner in React Native and struggling in passing and executing functions as props from parent to child component. Here's the code:
MainMap
import React from 'react';
import {
TouchableWithoutFeedback,
StyleSheet,
View,
Button,
FlatList,
Dimensions
} from 'react-native';
import PlaceInput from '../components/PlaceInput';
const INCREMENT = 1;
const HEIGHT = Dimensions.get('window').height
const WIDTH = Dimensions.get('window').width
class MainMap extends React.Component{
constructor(props){
super(props);
this.state={
numOfInput:[],
counter: 0,
}
this.onAddSearch = this.onAddSearch.bind(this)
this.onDeleteSearch = this.onDeleteSearch.bind(this)
}
onAddSearch(){
this.setState((state) => ({
counter: state.counter + INCREMENT,
numOfInput: [...state.numOfInput, state.counter]
}))
}
onDeleteSearch(inputId){
const items = this.state.numOfInput.filter(item => item.id !== inputId)
this.setState({
numOfInput: items
})
}
render(){
return(
<TouchableWithoutFeedback onPress={this.hideKeyboard} >
<View style={styles.container} >
<Button title='Add a location' onPress={this.onAddSearch} />
<View style={{height: HEIGHT/2 }}>
<FlatList
data={this.state.numOfInput}
keyExtractor={(item, index) => item.id}
renderItem={itemData => {
return(
<PlaceInput
key={itemData.item.id}
// id={itemData.item.id}
onDelete={this.onDeleteSearch}
showDirectionOnMap={this.showDirectionOnMap}
userLatitude={userLatitude}
userLongitude={userLongitude}
/>
)
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
)
}
}
export default MainMap;
const styles = StyleSheet.create({
container:{
flex: 1
},
})
Here's the PlaceInput component
class PlaceInput extends React.Component{
constructor(props){
super(props);
... // These lines have no relation to what I'm asking so don't mind them
}
...
render(){
return(
<View style={styles.buttonContainer} >
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{fontSize: 8}}>{'\u25A0'}</Text>
</View>
<View style={{flex: 4}}>
<TextInput
autoCorrect={false}
autoCapitalize='none'
style={styles.inputStyle}
placeholder='Search your places'
onChangeText={(input) => {
this.setState({destinationInput: input});
this.getPlacesDebounced(input);
}}
value={this.state.destinationInput}
/>
{/* {predictions} */}
</View>
<View style={styles.rightCol}>
<TouchableOpacity onPress={this.props.onDelete.bind(this, this.props.id)}>
<Ionicons name='md-car' size={25} style={{alignSelf: 'center'}} />
</TouchableOpacity>
</View>
</View>
)
}
}
What I'm trying to do:
Define a function to execute in MainMap.js (in FlatList --> PlaceInput for specific) , which is to delete an search bar( the whole PlaceInput in the FlatList) every time I click the right symbol of that search bar. The function is onDeleteSearch
The right symbol is styled in a TouachableOpacity as you can see in the PlaceInput.js component. I put it in the last View pair
However, When I click, the screen deletes all the search bars, not the one I click. Is it the problem of the id of the component PlaceInput ? Or with the way I call the props?...
Please help me !
<TouchableOpacity onPress={this.props.onDelete.bind(this, this.props.id)}>
<Ionicons name='md-car' size={25} style={{alignSelf: 'center'}} />
</TouchableOpacity>
Don't bind, just call this.props.onDelete(this.props.id);
In MainMap, try this:
<PlaceInput
key={itemData.item.id}
// id={itemData.item.id}
onDelete={() => this.onDeleteSearch(itemData.item.id)} // here
showDirectionOnMap={this.showDirectionOnMap}
userLatitude={userLatitude}
userLongitude={userLongitude}
/>
Assuming the function:
onPressed(optionalArgument = false) {
// do something
}
You can pass a function to onPress if it does not require any arguments, i.e
onPress={onPressed} // - would work if no arguments required.
onPress={onPressed(argument)} // - will get fired on component render
onPress={()=> onPressed(argument)} // - will work as expected on button press
onPress={()=> { // - will work as expected on button press
// Multiple lines of code
onPressed(argument);
anotherFunction();
}
};
In your MainMap you are doing everything correctly, just uncomment the
// id={itemdata.item.id}
In PlaceInput, just one small change:
<TouchableOpacity onPress={() => this.props.onDelete(this.props.id)}>
<Ionicons name='md-car' size={25} style={{alignSelf: 'center'}} />
</TouchableOpacity>
If you don't add ()=> to your onPress, the function gets called immediately, that's why you see such behaviour.
Your numOfInput is just a list of numbers, so instead of using item.id-s use item directly.
Here:
const items = this.state.numOfInput.filter(item => item !== inputId)
And here
<PlaceInput
key={itemData.item}
// id={itemData.item}
...
/>

How to call a child method from the parent in React Native?

When a click event is fired within my parent component I need to call the method closeMenu() from the SearchBar child component. I have tried a couple of different ways to do that but none of them are working. Does anyone know how to do this?
class Products extends Component {
constructor(props) {
super(props);
this.state = { closeMenu: false};
this.hideSearchBar = this.hideSearchBar.bind(this);
}
hideSearchBar(e) {
console.log('e: ', React.Children)
this.setState({closeMenu: true});
this.refs.SearchBar.closeMenu();
this.setState({closeMenu: false});
}
componentWillMount() {
this.props.dispatch(getProductList());
}
render() {
const {isLoading, products} = this.props.products;
if (isLoading) {
return <Loader isVisible={true}/>;
}
return (
<TouchableWithoutFeedback onPress={(e) => this.hideSearchBar(e)} style={{zIndex: 0}}>
<View style={styles.wrapper}>
<Header/>
<View style={styles.bodyWrapper}>
<ScrollView style={styles.scrollView}>
<ProductsContainer data={{productsList: { results: products }}}/>
</ScrollView>
<SearchBar ref="SearchBar" style={styles.searchBar} />
</View>
<Footer/>
</View>
</TouchableWithoutFeedback>
);
}
}
I also tried calling closeMenu() without refs:
hideSearchBar(e) {
this.setState({closeMenu: true});
this.SearchBar.closeMenu();
}
Here is the SearchBar component:
class SearchBar extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.suggestions = [];
}
componentWillUpdate(nextProps, nextState) {
console.log("COMPONENT WILL UPDATE");
console.log(nextProps);
console.log(nextState);
}
suggestionClick = (value) => {
}
getSuggestionText = (suggestion) => {
}
onChangeText = (value) => {
this.selectedSuggestion = false
this.props.dispatch(handleSearchItemText(value));
console.log(this.props.products.searchResults);
}
onFocus() {
const {height} = Dimensions.get('window');
this.setState({
contentOffset: {
x: 0,
y: height * 1 / 3
}
});
}
onBlur() {
this.setState({
contentOffset: {x: 0, y: 0}
});
}
closeMenu = () => {
this.props.products.searchResults = {};
}
componentWillReceiveProps() {
if (!this.props.closeMenu) {
this.props.closeMenu = false;
}
}
renderSearches = () => {
this.suggestions = this.props.products.searchResults;
const suggestionTexts = Object.keys(this.props.products.searchResults || {})
console.log(suggestionTexts);
if (!suggestionTexts.length) {
return null
}
// for android absolute element: https://github.com/facebook/react-native/issues/16951
// https://gist.github.com/tioback/6af21db0685cd3b1de28b84981f31cca#file-input-with-suggestions-L54
return (
<View
ref="suggestionsWrapper"
style={autoStyles.suggestionsWrapper}
>
{
this.suggestions.map((text, index) => (
<TouchableHighlight
key={index}
suggestionText={text}
activeOpacity={0.6}
style={autoStyles.suggestion}
onPress={this.suggestionClick(this.suggestions[text])}
underlayColor='white'
>
<Text style={autoStyles.suggestionText}>
{text}
</Text>
</TouchableHighlight>
))
}
</View>
)
}
render() {
const myIcon = (<Icon name="search" size={30} style={styles.searchIcon}/>);
const slidersIcon = (<Icon name="sliders" size={30} style={styles.slidersIcon}/>);
return (
<TouchableWithoutFeedback style={{zIndex: 0}}>
<View style={[styles.searchBar, this.props.style]}>
<View style={styles.searchContainer}>
<View>
{slidersIcon}
</View>
<View style={styles.search}>
<View style={styles.searchSection}>
{myIcon}
<TextInput
style={styles.input}
placeholder="Search"
placeholderTextColor="rgba(0,0,0,0.7)"
onChangeText={(searchString) => {
this.setState({searchString})
}}
underlineColorAndroid="transparent"
editable={true}
autoCorrect={false}
autoFocus={false}
autoCaptialize={'none'}
autoCorrect={false}
onChangeText={this.onChangeText}
enablesReturnKeyAutomatically={true}
onFocus={() => this.onFocus()}
onBlur={() => this.onBlur()}
/>
</View>
</View>
</View>
{this.renderSearches()}
</View>
</TouchableWithoutFeedback>
);
}
}
There are some issues which you should avoid:
Never mutate props: this.props.something = {} is an anti-pattern. Think about props as data that your component does not own and which are not mutable. If they change then only because the parent passed new props.
Also you have multiple handlers in your SeachBar that are not bound to this but use this. It will not work. Use arrow functions if you want to use this or bind them in the constructor.
You should overthink the architecture of your app. Maybe it is a good idea to split the search bar and the result list into two separate components. When the user types something to search for update your redux store and display the results in a separate component that you only render if there are search results.
I'm affraid it would exceed the length of a stackoverflow answer to solve all these issues. Maybe you should go back to the basics first and do the really good redux tutorial.

Undefined TextInput Value

I want to submit value from text input, but when I console.log, the text that inputed before is undefined. I've already follow the instruction from react native get TextInput value, but still undefined.
this is state that I've made before:
this.state = {
comment_value: '',
comments: props.comments
}
submit = (args) => {
this.props.submit(args.comment_value)
}
this is the the function for submitted text:
addComment () {
var comment_value = this.state.comment_value
console.log('success!', comment_value)
})
this.props.submit('410c8d94985511e7b308b870f44877c8', '', 'e18e4e557de511e7b664b870f44877c8')
}
and this is my textinput code:
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
onChangeText={(text) => this.setState({comment_value: text})}
value={this.state.comment_value}
style={styles.textinput}
/>
</View>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
This should definately be working try cleaning up your code like this
contructor(props) {
super(props);
this.state = {
comment_value: '',
}
}
addComment () {
console.log(this.state.comment_value); // should be defined
this.props.submit(this.state.comment_value);
}
render() {
return (
<View>
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
value={this.state.comment_value}
onChangeText={(text) => this.setState({comment_value: text})}
style={styles.textinput}
/>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
</View>
);
}
EDIT: Based on your complete code sample it seems like you're incorrectly trying to update state by doing multiple this.state = ... which is incorrect, to update state you have to use this.setState({ ... })

How refresh the ListView Component in react native?

I'm trying to create a todo list, then I'm trying to use this checkbox package
react-native-check-box
I don't know if this issue come from that package
when I click the checkbox and click the delete button this is what happen
And here is my code for displaying the list
interface TodoProps{
todo: TodoModel;
ter:string;
}
interface TodoState{
dataSource: any;
myTodo: Array<ITodo>;
}
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => true});
export default class Todo extends React.Component <TodoProps,TodoState>{
constructor(props:TodoProps) {
super(props);
this.state = {
dataSource: ds.cloneWithRows([]), // or put your initial data here
myTodo: []
};
}
componentWillReceiveProps = (nextProps) => {
console.log(this.state.myTodo);
let data = {
title: nextProps.ter,
isChecked: false
};
let todoList = this.state.myTodo;
if (nextProps.ter) {
todoList.push(data);
}
this.setState({
myTodo: todoList
});
}
onDelete(){
let todos = this.state.myTodo.filter((todo:ITodo) => {
return !todo.isChecked;
});
this.setState({
myTodo: todos
});
}
render() {
let dataSource = this.state.dataSource.cloneWithRows(this.state.myTodo);
return (
<View style={styles.container}>
<View style={styles.box2}>
<ListView enableEmptySections={true} dataSource={dataSource} renderRow={(rowData, sectionID, rowID) => <TodoList data={rowData} onClick={this.onClick.bind(this)} id={rowID} /> } />
</View>
<View style={styles.box3}>
<TouchableOpacity style={styles.bbox1} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>All</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox2} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>Complete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox3} onPress={()=> alert('weee')}>
<Text style={styles.tabText}>InComplete</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bbox4} onPress={()=> this.onDestroy()}>
<Text style={styles.tabText}>Delete</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
But if I console log the data. I find all isChecke: to false. Only the view of checkbox is not working. Do I need to use componentwillamount() for this?
Use the below sample code
_onRefresh() {
this.setState({refreshing: true});
// your callback function or call this.componentDidMount()
}
render() {
return (
<ListView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
...
>
...
</ListView>
);
}

Hide/Show components in react native

I'm really new to React Native and I'm wondering how can I hide/show a component.
Here's my test case:
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => this.doSearch({input: text})} />
<TouchableHighlight
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
I have a TextInput component, what I want is to show the TouchableHighlight when the input gets the focus, then hide the TouchableHighlight when the user press the cancel button.
I donĀ“t know how to "access" the TouchableHighlight component in order to hide/show it inside of my functions showCancel/hideCancel.
Also, how can I hide the button from the very beginning?
In your render function:
{ this.state.showTheThing &&
<TextInput/>
}
Then just do:
this.setState({showTheThing: true}) // to show it
this.setState({showTheThing: false}) // to hide it
I would do something like this:
var myComponent = React.createComponent({
getInitialState: function () {
return {
showCancel: false,
};
},
toggleCancel: function () {
this.setState({
showCancel: !this.state.showCancel
});
}
_renderCancel: function () {
if (this.state.showCancel) {
return (
<TouchableHighlight
onPress={this.toggleCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
);
} else {
return null;
}
},
render: function () {
return (
<TextInput
onFocus={this.toggleCancel()}
onChangeText={(text) => this.doSearch({input: text})} />
{this._renderCancel()}
);
}
});
In react or react native the way component hide/show or add/remove does not work like in android or iOS. Most of us think there would be the similar strategy like
View.hide = true or parentView.addSubView(childView)
But the way react native work is completely different. The only way to achieve this kind of functionality is to include your component in your DOM or remove from DOM.
Here in this example I am going set the visibility of text view based on the button click.
The idea behind this task is the create a state variable called state having the initial value set to false when the button click event happens then it value toggles. Now we will use this state variable during the creation of component.
import renderIf from './renderIf'
class FetchSample extends Component {
constructor(){
super();
this.state ={
status:false
}
}
toggleStatus(){
this.setState({
status:!this.state.status
});
console.log('toggle button handler: '+ this.state.status);
}
render() {
return (
<View style={styles.container}>
{renderIf(this.state.status)(
<Text style={styles.welcome}>
I am dynamic text View
</Text>
)}
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text>
touchme
</Text>
</TouchableHighlight>
</View>
);
}
}
the only one thing to notice in this snippet is renderIf which is actually a function which will return the component passed to it based on the boolean value passed to it.
renderIf(predicate)(element)
renderif.js
'use strict';
const isFunction = input => typeof input === 'function';
export default predicate => elemOrThunk =>
predicate ? (isFunction(elemOrThunk) ? elemOrThunk() : elemOrThunk) : null;
React Native's layout has the display property support, similar to CSS.
Possible values: none and flex (default).
https://facebook.github.io/react-native/docs/layout-props#display
<View style={{display: 'none'}}> </View>
in render() you can conditionally show the JSX or return null as in:
render(){
return({yourCondition ? <yourComponent /> : null});
}
Most of the time i'm doing something like this :
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {isHidden: false};
this.onPress = this.onPress.bind(this);
}
onPress() {
this.setState({isHidden: !this.state.isHidden})
}
render() {
return (
<View style={styles.myStyle}>
{this.state.isHidden ? <ToHideAndShowComponent/> : null}
<Button title={this.state.isHidden ? "SHOW" : "HIDE"} onPress={this.onPress} />
</View>
);
}
}
If you're kind of new to programming, this line must be strange to you :
{this.state.isHidden ? <ToHideAndShowComponent/> : null}
This line is equivalent to
if (this.state.isHidden)
{
return ( <ToHideAndShowComponent/> );
}
else
{
return null;
}
But you can't write an if/else condition in JSX content (e.g. the return() part of a render function) so you'll have to use this notation.
This little trick can be very useful in many cases and I suggest you to use it in your developments because you can quickly check a condition.
Regards,
EDIT: For a more straight forward synthax, you can do {this.state.isHidden && <ToHideAndShowComponent/>}. Here, the left operand is evaluated before the right one, so if isHidden is false, then the component will not show up.
just use
style={ width:0, height:0 } // to hide
I needed to switch between two images. With conditional switching between them there was 5sec delay with no image displayed.
I'm using approach from downvoted amos answer. Posting as new answer because it's hard to put code into comment with proper formatting.
Render function:
<View style={styles.logoWrapper}>
<Image
style={[styles.logo, loading ? styles.hidden : {}]}
source={require('./logo.png')} />
<Image
style={[styles.logo, loading ? {} : styles.hidden]}
source={require('./logo_spin.gif')} />
</View>
Styles:
var styles = StyleSheet.create({
logo: {
width: 200,
height: 200,
},
hidden: {
width: 0,
height: 0,
},
});
Hide And Show parent view of Activity Indicator
constructor(props) {
super(props)
this.state = {
isHidden: false
}
}
Hide and Show as Follow
{
this.state.isHidden ? <View style={style.activityContainer} hide={false}><ActivityIndicator size="small" color="#00ff00" animating={true}/></View> : null
}
Full reference
render() {
return (
<View style={style.mainViewStyle}>
<View style={style.signinStyle}>
<TextField placeholder='First Name' keyboardType='default' onChangeFirstName={(text) => this.setState({firstName: text.text})}/>
<TextField placeholder='Last Name' keyboardType='default' onChangeFirstName={(text) => this.setState({lastName: text.text})}/>
<TextField placeholder='Email' keyboardType='email-address' onChangeFirstName={(text) => this.setState({email: text.text})}/>
<TextField placeholder='Phone Number' keyboardType='phone-pad' onChangeFirstName={(text) => this.setState({phone: text.text})}/>
<TextField placeholder='Password' secureTextEntry={true} keyboardType='default' onChangeFirstName={(text) => this.setState({password: text.text})}/>
<Button style={AppStyleSheet.buttonStyle} title='Sign up' onPress={() => this.onSignupPress()} color='red' backgroundColor='black'/>
</View>
{
this.state.isHidden ? <View style={style.activityContainer}><ActivityIndicator size="small" color="#00ff00" animating={true}/></View> : null
}
</View>
);
}
On Button presss set state as follow
onSignupPress() {
this.setState({isHidden: true})
}
When you need to hide
this.setState({isHidden: false})
I had the same issue where I would want to show / hide Views, but I really didn't want the UI jumping around when things were added/removed or necessarily to deal with re-rendering.
I wrote a simple Component to deal with it for me. Animated by default, but easy to toggle. I put it on GitHub and NPM with a readme, but all the code is below.
npm install --save react-native-hideable-view
import React, { Component, PropTypes } from 'react';
import { Animated } from 'react-native';
class HideableView extends Component {
constructor(props) {
super(props);
this.state = {
opacity: new Animated.Value(this.props.visible ? 1 : 0)
}
}
animate(show) {
const duration = this.props.duration ? parseInt(this.props.duration) : 500;
Animated.timing(
this.state.opacity, {
toValue: show ? 1 : 0,
duration: !this.props.noAnimation ? duration : 0
}
).start();
}
shouldComponentUpdate(nextProps) {
return this.props.visible !== nextProps.visible;
}
componentWillUpdate(nextProps, nextState) {
if (this.props.visible !== nextProps.visible) {
this.animate(nextProps.visible);
}
}
render() {
if (this.props.removeWhenHidden) {
return (this.visible && this.props.children);
}
return (
<Animated.View style={{opacity: this.state.opacity}}>
{this.props.children}
</Animated.View>
)
}
}
HideableView.propTypes = {
visible: PropTypes.bool.isRequired,
duration: PropTypes.number,
removeWhenHidden: PropTypes.bool,
noAnimation: PropTypes.bool
}
export default HideableView;
An additional option is to apply absolute positioning via styling, setting the hidden component in out-of-screen coordinates:
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => this.doSearch({input: text})}
style={this.state.hide ? {position: 'absolute', top: -200} : {}}
/>
Unlike in some of the previous suggestions, this would hide your component from view BUT will also render it (keep it in the DOM), thus making it truly invisible.
constructor(props) {
super(props);
this.state = {
visible: true,
}
}
declare visible false so by default modal / view are hide
example = () => {
this.setState({ visible: !this.state.visible })
}
**Function call **
{this.state.visible == false ?
<View>
<TouchableOpacity
onPress= {() => this.example()}> // call function
<Text>
show view
</Text>
</TouchableOpacity>
</View>
:
<View>
<TouchableOpacity
onPress= {() => this.example()}>
<Text>
hide view
</Text>
</TouchableOpacity>
</View>
}
If you need the component to remain loaded but hidden you can set the opacity to 0. (I needed this for expo camera for instance)
//in constructor
this.state = {opacity: 100}
/in component
style = {{opacity: this.state.opacity}}
//when you want to hide
this.setState({opacity: 0})
Three ways to show\hide components:
- Class Component: / ------------------------------------------------------------------------------------------------------------
in all examples i used below state:
.
...
constructor(props) {
super(props);
this.state = {showComponent: true};
}
1. using display prop
<View display={this.state.showComponent ? 'flex' : 'none'} />
2. using display prop with style
<View style={{display:this.state.showComponent ? 'flex' : 'none'}} />
3. limit render
{
this.state.showComponent &&
<View /> // Or <View> ... </View>
}
- Functional Component:/ ------------------------------------------------------------------------------------------------------------
in all examples i used below state:
const [showComponent, setShowComponent] = useState(true);
1. using display prop
<View display={showComponent ? 'flex' : 'none'} />
2. using display prop with style
<View style={{showComponent ? 'flex' : 'none'}} />
3. limit render
{
showComponent &&
<View /> // Or <View> ... </View>
}
// You can use a state to control wether the component is showing or not
const [show, setShow] = useState(false); // By default won't show
// In return(
{
show && <ComponentName />
}
/* Use this to toggle the state, this could be in a function in the
main javascript or could be triggered by an onPress */
show == true ? setShow(false) : setShow(true)
// Example:
const triggerComponent = () => {
show == true ? setShow(false) : setShow(true)
}
// Or
<SomeComponent onPress={() => {show == true ? setShow(false) : setShow(true)}}/>
I usually use something like this
const [showComponent, setShowComponent] = useState(false)
return(
<div>
{showComponent && (<Text>Hello</Text>)}
<Button onPress={() => {setShowComponent(true)}}>Click me</Button>
</div>
)
It will show 'Hello' once the button is pressed. This is called conditional rendering. You can refer to w3schools to learn about conditional rendering.
You can use my module react-native-display to show/hide components.
The following example is coding in typescript with Hooks.
import React, { useState, useEffect } from "react";
........
const App = () => {
const [showScrollView, setShowScrollView] = useState(false);
......
const onPress = () => {
// toggle true or false
setShowScrollView(!showScrollView);
}
......
</MapboxGL.ShapeSource>
<View>{showScrollView ? (<DetailsScrollView />) : null}</View>
</MapboxGL.MapView>
......
}
I would vouch for using the opacity-method if you do not want to remove the component from your page, e.g. hiding a WebView.
<WebView
style={{opacity: 0}} // Hide component
source={{uri: 'https://www.google.com/'}}
/>
This is useful if you need to submit a form to a 3rd party website.
i am just using below method to hide or view a button. hope it will help you. just updating status and adding hide css is enough for me
constructor(props) {
super(props);
this.state = {
visibleStatus: false
};
}
updateStatusOfVisibility () {
this.setStatus({
visibleStatus: true
});
}
hideCancel() {
this.setStatus({visibleStatus: false});
}
render(){
return(
<View>
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => {this.doSearch({input: text}); this.updateStatusOfVisibility()}} />
<TouchableHighlight style={this.state.visibleStatus ? null : { display: "none" }}
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
</View>)
}
Actually, in iOS development by react-native when I use display: 'none' or something like below:
const styles = StyleSheet.create({
disappearImage: {
width: 0,
height: 0
}
});
The iOS doesn't load anything else of the Image component like onLoad or etc, so I decided to use something like below:
const styles = StyleSheet.create({
disappearImage: {
width: 1,
height: 1,
position: 'absolute',
top: -9000,
opacity: 0
}
});
If you want to hide it but keep the space occupied by the component like css's visibility: hidden setting in the component's style opacity: 0 should do the trick.
Depending on the component other steps in disabling the functionality might be required as interaction with an invisible item is possible.
Very Easy. Just change to () => this.showCancel() like below:
<TextInput
onFocus={() => this.showCancel() }
onChangeText={(text) => this.doSearch({input: text})} />
<TouchableHighlight
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
The only way to show or hide a component in react native is checking a value of a parameter of app state like state or props. I provided a complete example as below:
import React, {Component} from 'react';
import {View,Text,TextInput,TouchableHighlight} from 'react-native'
class App extends Component {
constructor(props){
super(props);
this.state={
show:false
}
}
showCancel=()=>{
this.setState({show:true})
};
hideCancel=()=>{
this.setState({show:false})
};
renderTouchableHighlight(){
if(this.state.show){
return(
<TouchableHighlight
style={{borderColor:'black',borderWidth:1,marginTop:20}}
onPress={this.hideCancel}>
<View>
<Text>Cancel</Text>
</View>
</TouchableHighlight>
)
}
return null;
}
render() {
return (
<View style={{justifyContent:'center',alignItems:'center',flex:1}}>
<TextInput
style={{borderColor:'black',borderBottomWidth:1}}
onFocus={this.showCancel}
/>
{this.renderTouchableHighlight()}
</View>
);
}
}
export default App;
You can use the conditions for show and hide the components
constructor(){
super();
this.state ={
isVisible:true
}
}
ToggleFunction = () => {
this.setState(state => ({
isVisible: !state.isVisible
}));
};
render() {
return (
<View style={styles.MainContainer}>
{
this.state.isVisible ? <Text style= {{ fontSize: 20, color: "red", textAlign: 'center' }}> Hello World! </Text> : null
}
<Button title="Toggle Visibility" onPress={this.ToggleFunction} />
</View>
);
}
I solve this problem like this:
<View style={{ display: stateLoad ? 'none' : undefined }} />
Just simply use this because I wanted to use the "useRef" conditions were not an option for me. You can use this suppose when you want to use useRef hook and press the button.
<Button
ref={uploadbtn}
buttonStyle={{ width: 0, height: 0, opacity: 0, display: "none" }}
onPress={pickImage}
/>
We now have hooks so I would recommend a reformat. Use hooks to turn components on/off.
const [modalVisible, setModalVisible] = setState(false);
Then have a button
<Button title="Press Me" onPress={() => {
setModalVisible(true);
}}
Then, inside your return statement
return(
<View>
{modalVisible &&
Insert modal code in here.
}
</View>
)
You can do it, using the useState Hook
The useState basically, is a feature which helps us preserve the values of variables even after multiple re-renders.
It acts a local state management tool, for storing values, after the component renders or re-renders.
In addition, to that you can also, trigger it to update the UI, by changing the value of the state variable.
const [show,setShow] = useState(true)
So, here we have destructured the, values that useState sends, first is the variable, through which we can get the value, and the second is a function through which we can update the state variables value.
So, in your case -
import React, {useState} from 'react';
import { Text, View, StyleSheet,Button } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
const [show,setShow] = useState(true)
return (
<View style={styles.container}>
{show && <Text style={styles.paragraph}>
Showing and Hiding using useState
</Text>}
<Button
title="Press me"
onPress={() => {setShow(!show)}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
In this example, on Button press, we are toggling the state variable from true to false.
You can show or hide JSX Code, using boolean conditions, which we are doing in this statement.
{show && <Text style={styles.paragraph}>
Showing and Hiding using useState
</Text>}
This is an quick and effective method of using state for UI manipulations.
checkincheckout = () => {
this.setState({ visible: !this.state.visible })
}
render() {
return (
{this.state.visible == false ?
<View style={{ alignItems: 'center', flexDirection: 'row', marginTop: 50 }}>
<View style={{ flex: 1, alignItems: 'center', flexDirection: 'column' }}>
<TouchableOpacity onPress={() => this.checkincheckout()}>
<Text style={{ color: 'white' }}>Click to Check in</Text>
</TouchableOpacity>
</View>
</View>
:
<View style={{ alignItems: 'center', flexDirection: 'row', marginTop: 50 }}>
<View style={{ flex: 1, alignItems: 'center', flexDirection: 'column' }}>
<TouchableOpacity onPress={() => this.checkincheckout()}>
<Text style={{ color: 'white' }}>Click to Check out</Text>
</TouchableOpacity>
</View>
</View>
}
);
}
thats all. enjoy your coding...

Categories

Resources