Adding a View By Clicking a Button- REACT NATIVE - react-native

How can I add a view to the bottom of the screen with the click of a button, which is at the top of the screen, in React Native?

you make the view at the bottom of the screen conditionally render based on a state and you set it that state to be true on the OnPress method of the button

I think it is better to learn more about state and props and other fundamental concepts in react/react-native first:
https://facebook.github.io/react-vr/docs/components-props-and-state.html
but here is how you can do this:
You need to define a state if you can view that section as
false
, then when the button pressed, change the value of that state to
true
import React from 'react';
import {Text,View,TouchableOpacity} from 'react-native';
export default class testComponent extends React.Component {
constructor(){
super()
this.state = {
viewSection :false
}
}
renderBottomComponent(){
if(this.state.viewSection) {
return (
<View>
<Text>Hi!</Text>
</View>
)
}
}
buttonPress=()=>{
this.setState({viewSection:true})
}
render() {
return (
<View >
<TouchableOpacity onPress={this.buttonPress}>
<Text> Click Me!</Text>
</TouchableOpacity>
{this.renderBottomComponent()}
</View>
);
}
}

You can try this,
According to my knowledge this is what you want
import React, { useState } from 'react';
import { Button, View } from 'react-native';
export default function Testing() {
const Square = () => (
<View style={{
width: 50,
height: 50,
margin: 10,
backgroundColor: "green",
}} />
);
const [squares, setSquares] = useState([<Square />, <Square />, <Square />]);
return (
<View >
{squares.map(v => v)}
<Button title='add' onPress={() => setSquares([...squares, <Square />])} />
</View >
)
}

Related

How to call a component onPress TouchableOpacity in react-native

I am using TouchableOpacity from react-native. The code is:
<TouchableOpacity onPress={onPress}>
<Text style={styles.supplementItem}>{item.item}</Text>
</TouchableOpacity>
where the OnPress function is as:
const onPress = () => (
// eslint-disable-next-line no-sequences
<Text style={styles.supplementItem}>Hello</Text>
this.setState({tempKey: tempKey + 1})
);
I looked at: this question and tried to do like it. But this is not working. I am setting my states as follows:
constructor(props) {
super(props);
this.state = {
tempKey: 0,
};
}
Kindly help me what I am doing wrong.
The question which you mentioned is using function based components and you are using class based components as you showed the costructor part which proves that.
So onPress must be a method in that class in your case, so you don't need the const keyword before it and you need to call it in this way ; this.onPress
In nutshell, your whole component should be like this;
import React from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
class YourComp extends React.Component {
constructor(props) {
super(props);
this.state = {
tempKey: 0,
show: false
};
}
onPress = () => {
// eslint-disable-next-line no-sequences
this.setState(prevState => ({tempKey: prevState.tempKey + 1}))
};
render() {
return (
<View>
<TouchableOpacity style={{height: 100, justifyContent: 'center', alignItems: 'center'}} onPress={() => this.onPress()}>
<Text>Hello (item.item in your case)</Text>
</TouchableOpacity>
<Text key={this.state.tempKey.toString()}>Hello {this.state.tempKey}</Text>
</View>
)
}
}
export default YourComp;
If you want to show some component conditionally;
this.state = {
...,
show: false
}
Then in the onPress method;
this.setState(prevState => ({show: !prevState.show})) // this will make <Text /> to toggle the modal when clicked.
Then in the render method;
<Text>
{this.state.show && (
<YourNewComponent />
) || null}
</Text>

React Native element only visible/usable after pressing a button

New to React Native, having a go at an app idea. Basically I'm just trying to create an TextInput element that appears when I press a Button. Below is my attempt. I'm trying to take advantage of state within my class, but something is off.
Expo is throwing an error of 'null is not an object (evaluating 'this.state.isShowingText')'.
Any ideas?
import React, { Component } from 'react';
import { TextInput, Alert, Button, ScrollView, Text, View, StyleSheet } from 'react-native';
export default class CoolComponent extends Component {
render() {
const nameAdd = () =>{
state = { isShowingText: true };
}
return (
<View style={{ alignItems: 'center', top: 50 }}>
<Title>Some Title</Title>
{this.state.isShowingText ? <TextInput></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={nameAdd}
/>
</View>
);
}
}
The way you handling state is wrong
import React, { Component } from 'react';
import { TextInput, Button, ScrollView, View } from 'react-native';
export default class CoolComponent extends Component {
state = {
isShowingText: false
}
nameAdd = () => {
this.setState({
isShowingText: true
})
}
render() {
return (
<View style={{ alignItems: 'center', top: 50 }}>
{this.state.isShowingText ? <TextInput style={{ width: '50', height: '50', borderWidth: 1 }}></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={this.nameAdd}
/>
</View>
);
}
}
Hope this helps you. Feel free for doubts.

react-native navigation in Flatlist component over multiple files

I am using react-navigation for navigation and right now i am trying to navigate between Screens using my flatlist. I want it so that when i click on an item in the list that i get send to the Details screen, but whenever i press on an item in the list with this code, nothing happens. I tried to pass the navigation property from the Homescreen component to the MyListItem Component but then i get undefined is not an Object error.
However, i have a Test TouchableOpacity in my Homescreen Component and if i click on that, i can navigate to the Details screen (See "Test" Text in Homescreen Component).
I think i did something wrong with the navigation property, but i have been searching everywhere and have not found a solution.
This is my App.js file with the StackNavigator:
import React from 'react';
import { createStackNavigator } from 'react-navigation'
import HomeScreen from './screens/HomeScreen'
import DetailScreen from './screens/DetailScreen'
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailScreen,
},
{
initialRouteName: 'Home',
navigationOptions: {
header: null,
},
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
This is my HomeScreen file where the Problem is happening:
import React from 'react'
import { StyleSheet, Text, View, TouchableOpacity, StatusBar,
FlatList, Image } from 'react-native'
import Data from '../data/Data'
class MyListItem extends React.Component {
render() {
return(
<View style={styles.container}>
<TouchableOpacity
onPress={this.props.handleOnPress}
>
<View style={{ flexDirection: 'row', heigth: 100, width: 100 }}>
<View>
<Image style={{ height: 50, width: 50, resizeMode: 'contain' }} source={require('../res/icon.png')} />
</View>
<View style={{ justifyContent: 'center' }}>
<Text>
{this.props.item.name}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
);
}
}
class HomeScreen extends React.Component {
handleOnPress = () => {
this.props.navigation.navigate('Details')
}
render() {
return (
<View>
<StatusBar hidden={true} />
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Details')}
>
<Text>Test</Text>
</TouchableOpacity>
<FlatList
data={Data}
renderItem={({ item }) =>
<MyListItem
item={item}
onPress={this.handleOnPress}
/>
}
/>
</View>
);
}
}
export default HomeScreen;
Ps: I run the Code on an Android emulator.
Edit: edited answer suggestion into code
Might be a typo mistake but, you try to navigate to navigate('Details') when you declared your screen as Detail
{
Home: HomeScreen,
Detail: DetailScreen, <----
},

React navigation this.props.navigation undefined

I have a custom header like this
import React from 'react';
import { View, TouchableOpacity, Text, StyleSheet, Image } from 'react-native';
import { Header, Left, Right, } from 'native-base';
import { Icon } from 'react-native-elements';
export default class MainHeader extends React.Component {
pressSearch() {
this.props.navigation.navigate('Login');
}
render () {
return(
<Header style={{paddingTop:25}}>
<Left style={{marginBottom:10}}>
<TouchableOpacity>
<View style={{flexDirection:'row'}}>
<Image
style={styles.stretch}
source={require('../images/logoforplay.png')}
/>
<Text style={styles.headerText} > Eventlinn </Text>
</View>
</TouchableOpacity>
</Left>
<Right>
<TouchableOpacity
style={styles.headerButton}
onPress={this.pressSearch.bind(this)}
>
<Icon
name={'search'}
/>
</TouchableOpacity>
<TouchableOpacity
style={styles.headerButton}
>
<Icon
name={'add-location'}
/>
</TouchableOpacity>
<TouchableOpacity
style={styles.headerButton}
>
<Icon
name={'notifications'}
/>
</TouchableOpacity>
</Right>
</Header>
)
}
}
const styles = StyleSheet.create ({
mainContainer: {
flex:1,
backgroundColor:'white'
},
cardContainer: {
flex:1
},
stretch: {
height:35,
width:35,
},
headerText: {
fontSize:24,
marginTop:3,
},
headerButton: {
marginBottom:10,
marginLeft:15
}
})
My problem navigation.navigate not working.My routers working well because i can navigate to 'login' with another screen.I read something about pure components but still dont understand how to solve this problem.What do you suggest ? By the way i am new to react native.
If your header isn't a route within your Router at the head of your app you will need to use withRouter from react-router
import {withNavigation} from 'react-navigation'
export default withNavigation(MainHeader)
Now you should be able to access this.props.navigation without directly passing it down as a prop from a parent component.
use import { withNavigation } from 'react-navigation'; at the top and then export default withNavigation(FilmItem); at the end.
See doc : https://reactnavigation.org/docs/en/connecting-navigation-prop.html

React Native conditional rendering not working

I want to have a side menu, with a list of categories and when the user selects a category, it should open a scrollable list, right below the category name, with all the pieces of that category.
So I created two list components, one for the categories (SideMenuList) and one for the furniture pieces. I figured I needed to use conditional rendering to render the second list when the user selects the category.
My code:
Side menu code from app.js
state = {
hideMenu: null,
hideList: null
}
sideMenuShow() {
if(!this.state.hideMenu) {
return(
<SideMenu>
<MenuButton onPress = {() => this.setState({hideMenu: true})}/>
<Text style = {{color: 'white', fontSize: 16, fontWeight: 'bold'}}>Furniture</Text>
<SideMenuList onPress = {() => this.setState({hideList: true})}>
{
this.state.hideList ? console.log('yes') : null
}
</SideMenuList>
</SideMenu>
);
}
else {
return(
<SmallSideMenu>
<MenuButton onPress = {() => this.setState({hideMenu: false})}/>
</SmallSideMenu>
);
}
}
SideMenuList.js
import React, { Component } from 'react';
import { View, FlatList, Text, TouchableOpacity } from 'react-native';
import { CardSection } from './common';
import SideMenuItem from './SideMenuItem';
class SideMenuList extends Component {
render() {
return (
<View style = {{flex: 1}}>
<FlatList
style = {{marginBottom: 2}}
data={[
{key: 'Test'},
{key: 'Test2'},
{key: 'Test3'},
{key: 'Test4'},
{key: 'Test5'}
]}
renderItem={({item}) =>
<TouchableOpacity>
<SideMenuItem
onPress = {this.props.onPress}
text={item.key}
>
{this.props.children}
</SideMenuItem>
</TouchableOpacity>}
/>
</View>
);
}
}
export default SideMenuList;
SideMenuItem.js code
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
const SideMenuItem = (props, {onPress}) => {
return (
<View
style = {{flex: 1}}>
<TouchableOpacity
onPress = {onPress}>
<Text style={styles.itemStyle}>{props.text}</Text>
</TouchableOpacity>
{props.children}
</View>
);
}
const styles = {
itemStyle: {
marginTop: 10,
marginRight: 20,
marginLeft: 10,
color: 'white'
}
};
export default SideMenuItem;
My problem right now is that my onPress event is not changing the value of my state property 'hideList', so I can't even check if my solution would actually work. I'm doing a console log when the value is true but it never appears in my console.
Thanks in advance.
You are rendering your SideMenuItem with a TouchableOpacity wrapping it (in your SideMenuList file).
Probably when you are pressing the button, it's triggering SideMenuList button, instead of SideMenuItem button.
Try to remove the TouchableOpacity from SideMenuList and check if it works.
Hope it helps