How to get a param of an id using react-navigation v5? - react-native

I'm trying to update an app I've developed using react-navigation v4.
Using react-navigation v4 I could get the id using something like console.log(navigation.getParam('id'));
But when I tried the same after updating to v5 of react-navigation it shows me an error and I can't find the right way to get the param id
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation }) {
console.log(navigation.getParam('id'));
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
The other screen where the id is located is it:
import React, { useContext } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import { Context } from '../../context/BlogContext';
import Icon from 'react-native-vector-icons/Feather'
export default function IndexScreen({ navigation }) {
const { state, addBlogPost, deleteBlogPost } = useContext(Context);
return (
<View style={styles.container}>
<Button
title="Add Post"
onPress={addBlogPost}
/>
<FlatList
data={state}
keyExtractor={(blogPost) => blogPost.title}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={
() => navigation.navigate('ShowScreen',
{ id: item.id })}>
<View style={styles.row}>
<Text style={styles.title}>
{item.title} -
{item.id}
</Text>
<TouchableOpacity onPress={() => deleteBlogPost(item.id)}>
<Icon style={styles.icon}
name="trash"
/>
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 30,
justifyContent: 'center',
alignItems: 'center'
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#333'
},
title: {
fontSize: 18
},
icon: {
fontSize: 24
}
});

You can get params using route.params in react navigation v5 more on that read here
just update your code to this
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation,route }) {
const {id} =route.params; //you will get id here via route
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});

you can simply access your parameters like this
const id = this.props.route.params.id
inside this.props.route.params you will get all paramaters :)

Related

Pass state value as props react native

I am trying to make a reusable text input component, but I want to grab the value that the user types to manipulate it on the App.js
TextInputComponent.js
import React, {useState} from 'react';
import { StyleSheet, View, TextInput } from 'react-native'
const TextInputComponent = (props) => {
const [text, onChangeText] = useState("")
return (
<View>
<TextInput style={styles.container} value={text} onChangeText={onChangeText} placeholder="Enter"/>
</View>
)
}
const styles = StyleSheet.create({
container: {
height: 50,
width: 200,
padding: 10,
margin: 10,
borderWidth: 1,
borderColor: "black",
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default TextInputComponent
App.js
import { StatusBar } from 'expo-status-bar';
import React, {useState} from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';
import TextInputComponent from './src/components/TextInputComponent';
export default function App() {
return (
<View style={styles.container}>
<View style={{flexDirection: 'row' }}>
<Text>Test</Text>
<TextInputComponent/>
<Button title="A" onPress={()=> console.log(-------> text value from TextInputComponent <-----)}></Button>
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
In order to access the state value created on the TextInputComponent.js what do I need to do?
One thing you can do is to pass a custom method through to the component and then use it as the onChangeText method:
const TextInputComponent = ({ customMethod }) => {
const [text, onChangeText] = useState("")
return (
<View>
<TextInput style={styles.container} value={text} onChangeText={(txt) => customMethod(txt)} placeholder="Enter"/>
</View>
)
}
Then in App.js you have the method:
customMethod = (txt) => {
// do something with txt variable
}
and:
<TextInputComponent customMethod={customMethod} />
Might require some tweaking to get it to work (I didn't test it), but that's the general idea.

React native button onpress show 2 new buttons and make other stuff unclickable

I want after press on the FloatingButton, to show 2 more buttons.
While I have these 2 buttons shown, I want to make the rest of this page to be uncklickable,
that the user has to press one of these to go on navigating.
This is my code:
import React from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
import FloatingButton from '../components/FloatingButton';
const DuellScreen = () => {
return (
<View style={{ flex: 1 }}>
<ScrollView style={styles.container2}>
<Text style={{ flex: 1 }}>body</Text>
</ScrollView>
<View style={styles.container}>
<FloatingButton/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 16,
flex: 1,
backgroundColor: '#fff',
justifyContent: 'flex-end',
alignItems: 'center'
},
container2: {
padding: 16,
flex: 5,
backgroundColor: '#fff',
},
});
export default DuellScreen
How can I do this, especially the 2 button visible after buttonpress + make the other things unclickable?
how about this:
import React, { useState } from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
import FloatingButton from '../components/FloatingButton';
const DuellScreen = (props) => {
const [active, setActive] = useState(true);
return (
<View style={{ flex: 1 }}>
<ScrollView style={styles.container2}>
<Text style={{ flex: 1 }}>body</Text>
</ScrollView>
<View style={styles.container}>
<FloatingButton onPress={active ? () => setActive(false) : () => {} } />
{!active ?
<View>
<FloatingButton onPress={() => props.navigation.navigate('OtherScreen')} />
<FloatingButton onPress={() => props.navigation.navigate('AnotherScreen')} />
</View>
: null}
</View>
</View>
)
}

React native Button not working when i tap it on my mobile using expo application

I am having a problem with my button. i have just started learning reactnative.
import { StatusBar } from 'expo-status-bar';
import React,{ useState } from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export default function App() {
const [name, setName] = useState('Hamza');
const clickHandler= () => {
setName('Awais');
};
return (
<View style={styles.container}>
<Text >My Name is { name }</Text>
<Text></Text>
<View style={styles.buttonContainer}>
<Button title='update State' onPress={ clickHandler }/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
buttonContainer:{
marginTop:20,
},
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Try this way
<Button title='update State' onPress={() => clickHandler() } />

React Native component loose arrangement when a new component is added

I have the following view in a React Native app:
And this is the code for it:
index.js
import React, {useContext} from 'react';
import {View, StyleSheet} from 'react-native';
import {Headline, Button, IconButton} from 'react-native-paper';
import ShoppingCartEntry from './ShoppingCartEntry';
import ShoppingCartContext from '../../context/shoppingCart/shoppingCartContext';
const ShoppingCartList = () => {
const {shoppingCart} = useContext(ShoppingCartContext);
const TotalPriceDisplay = () => {
let totalPrice = 0;
shoppingCart.map((entry) => {
totalPrice = totalPrice + (entry.product.price * entry.amount);
})
return (
<Headline>Total: {totalPrice}</Headline>
)
}
return (
<View style={styles.cartContainer}>
<View style={styles.icon}>
<IconButton icon='cart' color='black' size={40}/>
</View>
{shoppingCart.map((entry) => {
return (
<ShoppingCartEntry entry={entry} />
)
})}
<View style={styles.totalPrice}>
<TotalPriceDisplay />
<Button mode='contained'>
Comprar
</Button>
</View>
</View>
)
}
styles = StyleSheet.create({
cartContainer: {
flexDirection: 'column',
},
totalPrice: {
alignItems: 'center'
},
icon: {
alignItems: 'center'
}
})
export default ShoppingCartList;
ShoppingCartEntry.js
import React, {useContext} from 'react';
import {View, StyleSheet} from 'react-native';
import {Headline, IconButton, Text} from 'react-native-paper';
import ShoppingCartContext from '../../context/shoppingCart/shoppingCartContext';
const ShoppingCartEntry = ({entry}) => {
const {shoppingCartAppendProduct, shoppingCartUpdateProduct, shoppingCartRemoveProduct} = useContext(ShoppingCartContext);
const removeProduct = () => {
shoppingCartRemoveProduct(entry.product.id);
}
const Counter = () => {
return (
<View style={styles.counterContainer}>
<View style={styles.counter}>
<IconButton icon='plus' color='black' onPress={removeProduct} />
</View>
<View>
<Headline color='blue'>{entry.amount}</Headline>
</View>
<View style={styles.counter}>
<IconButton icon='minus' color='black' onPress={removeProduct} />
</View>
</View>
)
}
return (
<View style={styles.entryContainer}>
<View style={styles.button}>
<IconButton icon='delete' color='red' onPress={removeProduct} />
</View>
<View style={styles.name}>
<Headline>{entry.product.name}</Headline>
<Text>{entry.product.price}</Text>
</View>
<View style={styles.amount}>
<Counter />
<Text style={{textAlign: 'right'}}>{entry.product.price * entry.amount}</Text>
</View>
</View>
)
}
styles = StyleSheet.create({
entryContainer: {
flexDirection: 'row',
paddingBottom: 20,
paddingLeft: 20
},
name: {
flex: 0.5
},
amount: {
flex: 0.3
},
button: {
alignItems: 'flex-end',
flex: 0.1
},
counterContainer: {
flexDirection: 'row'
},
counter: {
alignItems: 'flex-end',
justifyContent: 'center',
flexDirection: 'row'
}
})
export default ShoppingCartEntry;
The problem is that when an element is removed from shoppingCart and the whole view is re rendered, it looses all its formatting:
I discovered that all I have to do is to change the StyleSheet.flexDirection for the container from row to column and, then, back to row again, and the view gets arranged again, but now with the new data.
I don't know if this is a development stage issue that I shouldn't care about for production, or if there is something I can do to avoid it.
You should add flex:1 to your base container styles for both your list and your item.
...
entryContainer: {
flex:1,
flexDirection: 'row',
paddingBottom: 20,
paddingLeft: 20
},
...
cartContainer: {
flex:1,
flexDirection: 'column',
},

How to navigate to other page after click on button in react native?

I am an beginner in react native.I want to display home page after logged in.I have install react-navigator using npm install and I have tried below code.
But I am getting below error, I tried to solve this. Still I have the error.
In App.js
//This is an example code for Bottom Navigation//
import React, { Component } from 'react';
//import react in our code.
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
//import all the basic component we have used
import { createStackNavigator, createAppContainer } from 'react-navigation';
export default class App extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginTop: 50, fontSize: 25 }}>Setting!</Text>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Go to Home Tab</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Detail Screen</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Profile Screen</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
width: 300,
marginTop: 16,
},
});
Can anyone assist me to solve this?
You can do it as following:
import React from "react";
import { View, Text } from "react-native";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
class LoginScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Login Screen</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
</View>
);
}
}
on App.js,
import React from 'react';
import { HomeScreen, LoginScreen } from '..'// should set the proper path.
const AppNavigator = createStackNavigator({
Login: LoginScreen,
Home: HomeScreen
});
const App = () => {
return <AppNavigator />;
}
export default App;