I'm very new to react native and am trying to pass two inputs between two pages by pressing a button but i'm not sure where i'm going wrong. My intention is to have one variable be "Book name" and the second be "number of pages". Any help would be very appreciated.
Page 1
const FirstPage = ({navigation}) => {
const [userName, setUserName] = useState('');
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Text style={styles.heading}>
React Native Pass Value From One Screen to Another
Using React Navigation
</Text>
<Text style={styles.textStyle}>
Please insert your name to pass it to second screen
</Text>
{/*Input to get the value from the user*/}
<TextInput
value={String}
onChangeText={(bookname) => setUserName(bookname)}
placeholder={'Enter Any value'}
style={styles.inputStyle}
/>
<TextInput
value={String}
onChangeText={(pagenum) => setUserName(pagenum)}
placeholder={'Enter Any value'}
style={styles.inputStyle}
/>
<Button
title="Go Next"
//Button Title
onPress={() =>
navigation.navigate('SecondPage', {
paramKey: pageNum,
paramKey: bookName,
})
}
/>
Page 2
const SecondPage = ({route}) => {
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Text style={styles.heading}>
React Native Pass Value From One Screen to Another
Using React Navigation
</Text>
<Text style={styles.textStyle}>
Values passed from First page: {route.params.paramKey}
</Text>
</View>
</SafeAreaView>
);
};
Here you can find a full example
import * as React from 'react';
import { Pressable, View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import {
createStackNavigator,
HeaderBackButton,
} from '#react-navigation/stack';
import { useNavigation, useRoute } from '#react-navigation/native';
function ScreenOne() {
const navigation = useNavigation();
const route = useRoute();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Screen {route?.params?.passedValue}</Text>
<Pressable
onPress={() => navigation.navigate('Two', { passedValue: 'Two : 2'})}
style={{ backgroundColor: 'plum', padding: 10 }}>
<Text>Navigate an pass</Text>
</Pressable>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="One" component={ScreenOne} />
<Stack.Screen name="Two" component={ScreenOne} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
<Button
title="Go Next"
//Button Title
onPress={() =>
navigation.navigate('SecondPage', {
paramKey: pageNum,
paramKey: bookName,
})
}
/>
You could use a shorthand:
<Button
title="Go Next"
//Button Title
onPress={() =>
navigation.navigate('SecondPage', {
pageNum, // same like pageNum: pageNum
bookName,// bookName: bookName
})
}
/>
Access params:
const SecondPage = ({route}) => {
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Text style={styles.heading}>
React Native Pass Value From One Screen to Another
Using React Navigation
</Text>
<Text style={styles.textStyle}>
Values passed from First page: {route.params.pageNum}
</Text>
<Text style={styles.textStyle}>
Values passed from First page: {route.params.bookName}
</Text>
</View>
</SafeAreaView>
);
};
Related
I have a FlatList nested in a SectionList as shown below.
There is always 3 sections (rows) and each section has a FlatList with a horizontal scroll.
Expected
On button click, invoking the scrollToEnd() function, to scroll all 3 flatlists from each section to end.
Problem
Only the bottom or last flatlist scrolls to the end.
I cannot figure out why this is - I thought the ref in the flatlist may only be referencing the last Flatlist rendered and not the other two, maybe? If so, any tips or suggestions are welcome. Thank you.
...
const flatlistRef = useRef();
const scrollToEnd = () => {
flatlistRef.current.scrollToEnd({ animating: true });
};
...
<SectionList
contentContainerStyle={styles.sectionListContainer}
stickySectionHeadersEnabled={false}
sections={myData}
renderSectionHeader={({ section }) => (
<>
<FlatList
horizontal
data={section.data}
contentContainerStyle={
styles.flatlistContainer
}
renderItem={({ item }) => (
<Button
onPress={() => updateData(item.id)}
>
<ListItem item={item} />
</Button>
)}
showsHorizontalScrollIndicator={false}
ref={flatlistRef}
/>
</>
)}
renderItem={({}) => {
return null;
}}
/>
I have also working on this but I found a solution where I can create a Section.List by using react-native-paper.
But you can also use the map function, Here is the code of that
import React from "react";
import {View,Text} from "react-native";
const App = () =>{
return(
<View style={{flex: 1}}>
{data.map((item, index) => (
<View key={index} style={{borderBottomColor: 'black', borderBottomWidth: 2}}>
<Text style={{fontSize: 30, fontWeight: 'bold'}}>{item.title}</Text>
{item.items && <>
{item.items.map((item, index) => (
<View key={index} style={{backgroundColor: '#7fc', borderBottomColor: 'blue', borderBottomWidth: 2}}>
<Text style={{fontSize: 20, marginLeft: 40, color: 'blue'}}>{item.title}</Text>
{item.items && <>
{item.items.map((item, index) => (
<View key={index} style={{backgroundColor: 'yellow', borderBottomColor: 'red', borderBottomWidth: 2}}>
<Text style={{fontSize: 16, marginLeft: 80,}}>{item.title}</Text>
</View>
))}
</>}
</View>
))}
</>}
</View>
))}
</View>
)
}
export default App;
I hope It will help.
Hello guys so I'm trying to create a to do list app and I want to use TouchableOpacity for the task status, when the user press it the task status will change. But for some reason the Touchable tag didn't work. I think it's because of the view on Home.JS. Can anyone help me to resolve this error ?
Here's my code
Home.js:
<View>
<View>
{taskItems.length > 0 ? (taskItems.map((item, index) => {
return (
<TouchableOpacity style={styles.taskWrapper} key={index} onPress={() => completeTask(index)}>
<Task text={item} />
</TouchableOpacity>
)
})) :
(
<View style={styles.noItemWrapper}>
<Text style={styles.noItem1}>There are no task</Text>
<Text style={styles.noItem2}>Make your first reminder</Text>
</View>
)
}
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "Android" ? "padding" : "height"}
style = {styles.writeTaskContainer}
>
<TextInput
style={styles.input}
placeholder={'Write your task'} value={task} onChangeText={text => setTask(text)}/>
<TouchableOpacity onPress={() => handleAddTask() }>
<View style={styles.ButtonWrapper}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
)
}
Task.js Code:
const Task = (props) => {
const[pressed, setPressed] = useState(false);
const onPressHandler = () =>{
setPressed(!pressed);
};
return (
<View style={styles.wrapper}>
<Text style={styles.taskList}>{props.text}</Text>
<TouchableOpacity style={{ ...{backgroundColor: pressed ? 'green' : '#ff3126'}, ...styles.taskStatus }} onPress={() => onPressHandler()}>
{pressed ?
<Text style={styles.statusText} onPress={() => onPressHandler()}>Done</Text>
:
<Text style={styles.statusText} onPress={() => onPressHandler()}>On Going</Text>
}
</TouchableOpacity>
</View>
)
}
Try to import TouchableOpacity from this:
import {TouchableOpacity} from 'react-native-gesture-handler';
Sometimes TouchableOpacity doesn't work well with position: 'absolute'.
I have a form with many TextInput field and I want to use a single handler function for each onChangeText prop.
It was easy in react as we can set state with [name] = value because handler gives us the event but in react native it gives us the value of the TextInput field.
My example is like this -
export const myForm = () => {
const [form, setForm] = useState({name: '', number: '', address: '' })
const onChangeHandler = (value) => {
// how to handle for each state field
}
return (
<View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.name}
name="name"
onChangeText={onChangeHandler}
></TextInput>
</View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.number}
name="number"
onChangeText={onChangeHandler}
></TextInput>
</View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.address}
name="address"
onChangeText={onChangeHandler}
></TextInput>
</View>
<TouchableOpacity
activeOpacity={0.6}
onPress={saveForm}
>
<Text style={{ color: '#fff' }}>SUBMIT</Text>
</TouchableOpacity>
<View> )}
Is there any way this can be done with React Hooks. Looked everywhere but didn't find a solution.
I know how to handle this form with class based components, I am not able to understand how can I achieve this with React Hooks.
Please HELP!!!
Could you pass the name of the form to your onChangeHandler along with the text input?
You could also use try using onChange instead of onChangeText?
const onChangeHandler = (name, value) => {
if(name=="address"){
//setState(value)
} else if (name=="number"){
//setState(value)
}
}
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.name}
name="name"
onChangeText={(value)=>onChangeHandler(name,value)}
></TextInput>
</View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.number}
name="number"
onChangeText={(value)=>onChangeHandler(name,value)}
></TextInput>
</View>
This is how I solved this. Thanks RossHochwert for the help. I just passed another argument in onChangeHandler, same as the property name which I used in useState.
export const myForm = () => {
const [form, setForm] = useState({name: '', number: '', address: '' })
const onChangeHandler = (value, name) => {
// how to handle for each state field
setForm(form => ({
...form,
[name]: value
}))
}
return (
<View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.name}
onChangeText={(value) => onChangeHandler(value, "name")}
></TextInput>
</View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.number}
onChangeText={(value) => onChangeHandler(value, "number")}
></TextInput>
</View>
<View style={styles.inputContainer}>
<Text>Product Name</Text>
<TextInput
value={form.address}
onChangeText={(value) => onChangeHandler(value, "address")}
></TextInput>
</View>
<TouchableOpacity
activeOpacity={0.6}
onPress={saveForm}
>
<Text style={{ color: '#fff' }}>SUBMIT</Text>
</TouchableOpacity>
<View> )}
When I click on the cross icon first time, it lowers the keyboard and on the second tap, it clears the text in the search bar. I wanted to clear the text on the first tap I have tried other solutions as well but nothing worked. How can i clear the text on the first click?
return (
<View style={styles.FlatList_header}>
<View style={styles.header_style}>
<Input
autoFocus={true}
style={styles.textInputStyle}
onChangeText={text => this.search(text)}
value={this.state.text}
/>
<Icon
name="close"
style={styles.crossIcon}
onPress={() => {
this.search('');
}}
/>
</View>
</View>
);
};
render() {
const {data, onPress} = this.props;
return (
<>
<SafeAreaView
style={{flex: 1, backgroundColor: customColor.defaultGreen}}>
<View style={styles.MainContainer}>
<FlatList
data={data}
renderItem={({item}) => (
<View
style={{
flex: 1,
borderWidth: 0.5,
borderColor: customColor.textLightGrey,
}}>
<Text
style={styles.FlatList_Item}
onPress={() => onPress(item)}>
{item?.taskName}
</Text>
</View>
)}
enableEmptySections={true}
ListHeaderComponent={this.Render_FlatList_Sticky_header}
keyExtractor={item => item.id}
/>
</View>
</SafeAreaView>
</>
);
}
}
In your onPress function do this.
onPress={() => {
Keyboard.dismiss()
this.search('');
this.setState(text: '')
}}
Also, you are not setting your state while onChangeText, Do this in your onChangeText
onChangeText={(text)=>this.setState({text})}
Edit: Add this into your FlatList
keyboardShouldPersistTaps='always'
Create a new state for ex: pressed.
If user touch the first time set true. And insert the if condition in the view.
<TouchableOpacity onPress={() => this.setState({ pressed: !this.state.pressed})}>
{this.state.pressed ? (
<Icon
name="close"
style={styles.crossIcon}
onPress={() => {
this.search('');
}}
/>
) : (
<Text>Clear</Text>
)}
</TouchableOpacity>
Here this is my app.js
const AppStackNavigator = createStackNavigator({
Login:{ screen: Login },
DrawerNav: { screen: DrawerNavigator },
})
class App extends React.Component{
render() {
return (
<AppStackNavigator/>
)
}
}
export default createAppContainer(AppStackNavigator);
And this is DrawerNavigator.js file
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Header>
<Left>
<Icon name = "menu" onPress={() => this.props.navigation.openDrawer()}/>
</Left>
</Header>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle Drawer"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
);
}
}
const CustomDrawerComponent = (props)=>(
<SafeAreaView>
<View style={{height:150, backgroundColor:'white', alignItems:'center', justifyContent:'center'}}>
<Image source={require('./logo.png')} style={{height:120, width:120, borderRadius:60}} />
</View>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView> )
const navigator = createDrawerNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {drawerLabel: 'HomeScreen',}
},
SettingsScreen: {
screen: SettingsScreen,
navigationOptions: {drawerLabel: 'SettingsScreen',}
}},
{
drawerPosition :"left", contentComponent:CustomDrawerComponent
});
export default createAppContainer(navigator);
And this is login.js
class Login extends React.Component{
constructor(props){
super(props);
}
static navigationOptions = {
title:'Welcome',
headerLeft:
<View style={{paddingLeft:16}}>
<Icon
name="md-menu"
size={30}
color='black'
onPress={() => this.props.navigation.openDrawer()} />
</View>
}
loginHandler= ()=>{
//this.props.navigation.navigate('DrawerNav')
this.props.navigation.openDrawer()
}
render(){
return(
<View style={styles.container}>
<View style={{alignItems:'center'}}>
<Button
title={'Login'}
onPress={this.loginHandler.bind(this)}/>
</View>
</View>
)
}
}
export default Login;
Now Whenever i click icon to open navigation drawer then error arises undefined is not an object (evaluating _this2.props.navigation).I have tried many possible ways but i couldnt solve this problem.How can i solve this ? I have registered login component inside stack navigator then also login component was not able access navigation props.
onPress={() => this.props.navigation.openDrawer()}
Error describes that this line inside static block in login.js contains error