React Failed to customise Material UI button - javascript

I was using this package material UI for a project. The version is rather old(v1) as I need it to be compatible to the project itself(using node 10.8)
Right now I am trying to use a round button (see this demo) I was trying to use a round mini button, it worked pretty well when I am not using any theme.
<Button
id={this.props.id}
variant="fab" mini
onClick={this.props.onClick}
color={this.state.clicked ? "primary" : 'default' }>
{sth}
</Button>
Then I was trying to change the colour of the button. I added a theme and use that theme to wrap on the button.
This is not the first time I did such thing, as I changed the colour for a number of buttons before by doing this(they're all rectangular contained buttons).
const confirm_theme = createMuiTheme({
palette: {
primary: {
main: '#006D8F',
contrastText: '#fff',
},
},
});
export class StyledButton extends Component {
constructor(props) {
super(props);
this.state = {
clicked: false,
};
}
handleClick = (e) => {
this.setState({ clicked: !this.state.clicked });
}
render(){
return (
<Row
style={{ paddingTop: 10, justifyContent: "center"}}>
<MuiThemeProvider theme={confirm_theme}>
<Button
variant="contained"
id={this.props.id}
onClick={this.props.onClick}
color={this.state.clicked ? 'default' : "primary"}>
{sth}
</Button>
</MuiThemeProvider>
</Row>
)
}
}
However, this time I failed to do so, when I use it on a round mini button.
There were no error messages, and the colour of the button has been changed successfully, but the button went blank.
Has anyone encountered something like this? Is it possible to fix?(I know my version is quite old, so I understand there might not be a solution)

Your handleClick function is never triggered.
So instead of passing this.props.onClick to the button component you can pass the handleClick function and then call your this.props.onClick function inside the handleClick.
const confirm_theme = createMuiTheme({
palette: {
primary: {
main: '#006D8F',
contrastText: '#fff',
},
},
});
export class StyledButton extends Component {
constructor(props) {
super(props);
this.state = {
clicked: false,
};
}
handleClick = (e) => {
this.setState({ clicked: !this.state.clicked });
this.props.onClick();
}
render(){
return (
<Row
style={{ paddingTop: 10, justifyContent: "center"}}>
<MuiThemeProvider theme={confirm_theme}>
<Button
variant="contained"
id={this.props.id}
onClick={this.handleClick}
color={this.state.clicked ? 'default' : "primary"}>
{sth}
</Button>
</MuiThemeProvider>
</Row>
)
}
}
Live demo:

Related

React component is not re-rendering multiple time

I am making an application in which i have a button which change the theme from dark to light of the component. my application works fine for the first time but it does not work on second attempt
for example : If i click the button first time then it will change the theme to the dark mode but when i want to change the theme into light mode then it does not work
import {
Button,
createMuiTheme,
Grid,
Paper,
Switch,
ThemeProvider,
Typography,
} from "#material-ui/core";
import React, { Component } from "react";
export default class Mode extends Component {
constructor(props) {
super(props);
this.state = {
switch: false,
};
this.darkTheme = createMuiTheme({
palette: {
type: "dark",
},
});
this.lightTheme = createMuiTheme({
palette: {
type: "light",
},
});
}
componentDidUpdate() {
console.log(this.state.switch);
}
render() {
return (
<div>
<ThemeProvider
theme={this.state.switch === true ? this.darkTheme : this.lightTheme}
> // <-- **Condition for changing the mode**
<Paper style={{ height: "100vh" }}>
<Grid container direction="column">
<Typography variant="h1">this is my app</Typography>
<Button variant="contained" color="primary">
A button
</Button>
<Button variant="contained" color="secondary">
Another button
</Button>
<Switch
checked={this.state.switch}
onChange={() =>
this.setState((prev) => ({ switch: !prev.switch }))
}
name="Dark Mode"
inputProps={{ "aria-label": "secondary checkbox" }}
/>
</Grid>
</Paper>
</ThemeProvider>
</div>
);
}
}
I am using material ui for this
I'm not sure why it changes only one time. But you can fix by create theme every render.
First, create function createTheme:
const createTheme = (isDark) =>
createMuiTheme({
palette: {
type: isDark ? "dark" : "light",
},
});
Then, update ThemeProvider like this:
<ThemeProvider theme={createTheme(this.state.switch)}>

How to control of open/close modal in react-native

I want to control of 'Opening and Closing Modals' without using Redux. If I use Redux, i create a variable as isVisible and control it with setting a value as true or false. But, If I dont use Redux, i cant solve problem that explained below.
It's the code that I call modal function.
<TouchableOpacity onPress={ () => this.setState({ visibleModal: true ])}>
<Text> Press me! </Text> </TouchableOpacity>
<ProfileModals isVisible={this.state.visibleModal} />
Main Modal function:
export default class ProfileModals extends Component {
state = {
visibleModal: this.props.isVisible,
modal: "changeName"
};
render() {
const {visibleModal} = this.state;
return (
<Modal
isVisible={this.state.visibleModal}
backdropColor="black"
backdropOpacity={0.5}
animationOut="fadeOut"
onBackdropPress={() => this.setState({ visibleModal: false })}
swipeDirection={"down"}
onSwipeComplete={() => this.setState({ visibleModal: false })}
>
<View>
<Text>Hello!</Text>
</View>
</Modal>
);
}
}
When I press the button at the first time, Modal run correctly. After closing the modal, I press the button second time, It doesn't run anymore. Because of this.state.visibleModal value (in ProfileModal Component) is false, not this.props.isVisible.
How can i solve this problem?
dont store the modal's visibility in the state of the modal component, allow it to flow through props from the parent, follow this approach:
class Parent extends Component {
state = {
modalVisible: false,
};
openModal = () => this.setState({ modalVisible: true });
closeModal = () => this.setState({ modalVisible: false });
render() {
const { modalVisible } = this.state;
return (
<OtherStuff>
<Button onPress={this.openModal} />
<MyModal
visible={modalVisible}
closeModal={this.closeModal}
/>
</OtherStuff>
);
}
}
class MyModal extends Component {
render() {
const { visible, closeModal } = this.props;
return (
<Modal isVisible={visible}>
<Button onPress={closeModal} />
</Modal>
);
}
}

Trying to inject a stack navigator into a component and getting error stating "you should only render one navigator"

I have a case where a feature contains a FlatList full of information, a search bar, sort button, and filter button.
For the sort and filter buttons I need to pull up a modal from the bottom that takes up half the screen.
I understand that React Navigation wants us to only create one 'root' navigator and all other navigators be dependents; however, in this particular case I would very much like to explicitly add a navigator to this page where a user presses on the filter button, brings up the modal, presses a filter option and then have the modal navigate to another filter subpage within the confines of its view, while maintaining the main page content and root navigation state in the background.
I remember implementing this in React Navigation V1.x, but does anyone know how to get around this in V2.x?
Rather than doing it with nested stack navigator and things, I've implemented your requirement using built-in react native modal.
App
import React, { Component } from 'react';
import { createStackNavigator } from 'react-navigation';
import { MainScreen } from './src/screens/MainScreen';
const RootStack = createStackNavigator(
{
MainScreen
},
{
navigationOptions: {
header: null
}
}
);
export default class App extends Component {
render() {
return (
<RootStack />
);
}
}
MainScreen
import { default as React, PureComponent } from 'react';
import { View, Text, Button, Alert, Modal } from 'react-native';
interface Props {
}
interface States {
num: number;
isFilterOneVisible: boolean;
isFilterTwoVisible: boolean;
}
export class MainScreen extends PureComponent<Props, States> {
state = {
num: 0,
isFilterOneVisible: false,
isFilterTwoVisible: false
}
render() {
return (
<View
flex={1}
justifyContent={'space-evenly'}
alignItems={'center'}
>
<Text style={{ fontSize: 50 }}>{this.state.num}</Text>
<Button
title={'CHANGE STATE'}
onPress={() => {
this.setState((prevState: States) => ({
num: prevState.num + 1
}));
}}
/>
{/* Search */}
<Button
title={'Search'}
onPress={() => {
Alert.alert('Search', 'Search clicked');
}}
/>
{/* Sort*/}
<Button
title={'Sort'}
onPress={() => {
Alert.alert('Sort Clicked', 'Sort clicked')
}}
/>
<Button
title={'Filter'}
onPress={() => {
this.setState({
isFilterOneVisible: true
})
}}
/>
{/* Filter Modal 1*/}
<Modal
visible={this.state.isFilterOneVisible}
transparent={true}
animationType={'slide'}
onRequestClose={() => {
this.setState({
isFilterOneVisible: false
})
}}
>
<View
flex={1}
justifyContent={'flex-end'}
backgroundColor={'rgba(0,0,0,0.2)'}
>
{/* Bottom */}
<View
justifyContent={'center'}
alignItems={'center'}
backgroundColor={'white'}
height={200}
>
<Button
title={'GO TO NEXT FILTER STATE'}
onPress={() => {
this.setState({
isFilterOneVisible: false,
isFilterTwoVisible: true
})
}}
/>
</View>
</View>
</Modal>
{/* Filter Modal Two */}
<Modal
visible={this.state.isFilterTwoVisible}
transparent={true}
animationType={'slide'}
onRequestClose={() => {
this.setState({
isFilterTwoVisible: false
})
}}
>
<View
flex={1}
justifyContent={'flex-end'}
backgroundColor={'rgba(0,0,0,0.2)'}
>
{/* Bottom */}
<View
justifyContent={'center'}
alignItems={'center'}
backgroundColor={'white'}
height={200}
>
<Button
title={'SET DATA AS 1000'}
onPress={() => {
this.setState({
isFilterTwoVisible: false,
num: 1000
})
}}
/>
</View>
</View>
</Modal>
</ View >
);
}
}
NOTE: The code is not optimised and follows some bad patterns like arrow-methods-in-jsx. This is just a suggestion with a working example. Feel free to enhance the code and follow the divide-and-conquer strategy ;) . The full source code can be found from here

how to make a callback in reactnative

I have a dialog box that I want to present. I need an arrow function that allows me to call the callback prop that I have written as well as close the modal screen by the use of state. I am able to close it but not invoke the callbacks from the parent component
export class DialogBox extends PureComponent {
okButton = <Button type="text" title={t('action')} onPress={this.onOkPressed} />
cancelButton = <Button type="text" title={t('cancel')} onPress={this.onCancelPressed} />
confirmButtonBox = (
<Fragment>
{this.cancelButton}
{this.okButton}
</Fragment>
)
state = {
isVisible: this.props.isVisible,
}
onModalClose = () => {
this.setIsVisible(false)
}
onOkPressed = () => {
this.props.onOkPress()
this.onModalClose()
}
onCancelPressed = () => {
this.props.onCancelPress()
this.onModalClose()
}
setIsVisible (visible) {
this.setState({ isVisible: visible })
}
renderButtons (type) {
switch (type) {
case 'confirm':
return this.confirmButtonBox
case 'alert':
return this.okButton
default:
return this.okButton
}
}
render () {
const {
title, message, type,
} = this.props
return (
<Modal transparent animationType="fade" visible={this.state.isVisible}>
<View style={styles.container}>
<View style={styles.alertContainer}>
<View>
<Text>
<H3 style={{ fontWeight: 'bold' }}>
{title}
</H3>
</Text>
<Text>
{message}
</Text>
</View>
<View style={styles.buttons}>
{this.renderButtons(type)}
</View>
</View>
</View>
</Modal>
)
}
}
The way I need it to work is:
I have a container class external to this component which allows user to implement a callback method on Ok press and onCancle press.
class DialogBoxStoryContainer extends PureComponent {
// state = { isVisible: false, type: 'confirm' }
onOkPressed = () => {
// this.setState({ isVisible: false })
console.debug('on ok pressed')
}
onCancelPressed = () => {
// this.setState({ isVisible: false })
console.debug('on cancel pressed')
}
render () {
return (
<View>
<DialogBox
{...this.props}
onOkPress={this.onOkPressed}
onCancelPress={this.onCancelPressed}
isVisible="true"
type="confirm"
/>
I do not see the callbacks being executed here. What am i missing here?
Your code works for me. If your "Default Levels" in Chrome (I assume you are using Chrome) is not set for "Verbose", you can't see console.debug outputs. I don't know where this config is in Firefox or other browsers. So, if you are using another one just find this setting.

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