I am using useNavigation() to navigate from homescreen to another screen with onPress function inside TouchableOpacity. The navigation.navigate is not working. The onPress function call is successful but the screen is not navigating although the screen is named inside Navigation.stack().
Card component where the onPress is attached.
import { View, Text, TouchableOpacity,Image } from 'react-native'
import { StarIcon } from 'react-native-heroicons/solid'
import React from 'react'
import { MapPinIcon } from 'react-native-heroicons/outline'
import { urlFor } from '../sanity'
import { useNavigation } from '#react-navigation/native'
const RestaurantCards = ({
id,
imgUrl,
title,
rating,
type,
address,
shortDescription,
dishes,
longitude,
latitude
}) => {
const navigation = useNavigation()
return (
<View>
<TouchableOpacity
onPress = {()=>{
navigation.navigate('Restaurant',{
id,
imgUrl,
title,
rating,
type,
address,
shortDescription,
dishes,
longitude,
latitude
})
}}
className="bg-white mr-3 shadow"
>
<Image source = {{uri:urlFor(imgUrl).url()}} className = "h-36 rounded-sm object-cover"/>
<View className = "px-3 pb-4">
<Text className = "font-bold text-lg pt-2">{title}</Text>
<View className = "flex-row items-center space-x-1">
<StarIcon color={"green"} opacity = {0.5} size={22}/>
<Text className = "text-xs text-gray-500">
<Text className = "text-green-500">{rating}</Text> .{type}
</Text>
</View>
<View className="flex-row items-center space-x-1">
<MapPinIcon color="gray" opacity={0.4} size = {22}/>
<Text className="text-xs text-gray-500">NearBy - {address}</Text>
</View>
</View>
</TouchableOpacity>
</View>
)
}
export default RestaurantCards
This is where the Restaurant Cards are populated:
import { View, Text, ScrollView } from 'react-native'
import React, { useEffect, useState } from 'react'
import { ArrowRightIcon } from 'react-native-heroicons/outline'
import RestaurantCards from './RestaurantCards'
import SanityClient from '../sanity';
const FeaturedRow = ({id,featureTitle,description,featureCategory}) => {
const [restaurants,setRestaurants] = useState([])
useEffect(()=>{
SanityClient.fetch(
`
*[_type == "feature" && _id == $id]{
...,
restaurants[]->{
...,
dishes[]->,
type->{
name
}
}
}[0]
`,{id}
).then(data => {
setRestaurants(data?.restaurants)
}
)
},[restaurants])
return (
<View>
<View className = "justify-between flex-row items-center mt-4 px-4">
<Text className = "font-bold text-lg">{featureTitle}</Text>
<ArrowRightIcon color={"#F67511"}/>
</View>
<Text className="text-xs text-gray-500 px-4">
{description}
</Text>
<ScrollView horizontal
contentContainerStyle={{
paddingHorizontal:15
}}
showsHorizontalScrollIndicator = {false}
className = "pt-4"
>
{restaurants.map(restaurant => restaurant!=null &&(
<RestaurantCards
id = {restaurant._id}
imgUrl = {restaurant.image}
title = {restaurant.name.toString()}
rating = {restaurant.rating.toString()}
type = {restaurant._type.toString()}
address = {restaurant.address.toString()}
shortDescription ={restaurant.short_description.toString()}
dishes = {restaurant.dishes}
longitude = {restaurant.long.toString()}
latitude = {restaurant.lat.toString()}/>
))}
</ScrollView>
</View>
)
}
export default FeaturedRow
The home-screen that re-renders after the onPress on RestaurantCard is called.
HomeScreen.js
import { View, Text,Image, TextInput, ScrollView } from 'react-native'
import React, { useLayoutEffect } from 'react'
import { useNavigation } from '#react-navigation/native'
import { SafeAreaView } from 'react-native-safe-area-context'
import * as Icons from "react-native-heroicons/outline";
import Catagories from '../components/Catagories';
import FeaturedRow from '../components/FeaturedRow';
import { useState } from 'react';
import { useEffect } from 'react';
import SanityClient from '../sanity';
const HomeScreen = () => {
const navigation = useNavigation()
const [featureCategory,setFeatureCategory] = useState([])
useLayoutEffect(()=>{
navigation.setOptions({
headerShown: false,
})
},[])
useEffect(()=>{
console.log('use Effect called again')
SanityClient.fetch(`
*[_type == "feature"]{
...,
restaurants[]->{
...,
dishes[]->
}
}
`).then((data) => {
setFeatureCategory(data)
})
},[])
return (
<SafeAreaView className="bg-white pt-5">
<View className = "flex-row pb-3 items-center mx-4 space-x-2">
<Image
source = {{uri:"https://i.ibb.co/ZYvGfFY/Untitled-design-7.png"}}
className = "h-7 w-7 bg-gray-300 p-4 rounded-full"
/>
<View className="flex-1">
<Text className = "font-bold text-gray-400 text-xs">Deliver Now!</Text>
<Text className = "font-bold text-xl">
Current Location
<Icons.ChevronDownIcon size={20} color="#F67511" />
</Text>
</View>
<Icons.UserIcon size={25} color="#F67511"/>
</View>
<View className="flex-row items-center space-x-2 pb-2 mx-4">
<View className="flex-row space-x-2 flex-1 bg-gray-100 p-3">
<Icons.MagnifyingGlassIcon color="#F67511" size={20}/>
<TextInput placeholder="Restaurants and Cafe" keyboardType="default"/>
</View>
<Icons.AdjustmentsVerticalIcon color="#F67511"/>
</View>
{/* Body */}
<ScrollView className="bg-gray-100"
contentContainerStyle={{
paddingBottom:100
}}>
<Catagories/>
{featureCategory?.map(category=>(
<FeaturedRow
id={category._id}
featureTitle={category.name}
description={category.short_description}
/>
))}
</ScrollView>
</SafeAreaView>
)
}
export default HomeScreen
The expected Screen where it should navigate to:
import { View, Text } from 'react-native'
import React from 'react'
const RestaurantScreen = () => {
return (
<View>
<Text>RestaurantScreen</Text>
</View>
)
}
export default RestaurantScreen
The main App component where the navigation screens name are set.
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import HomeScreen from './screens/HomeScreen';
import RestaurantScreen from './screens/HomeScreen';
export default function App() {
const Stack = createStackNavigator()
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Home' component={HomeScreen}/>
<Stack.Screen name='Restaurant' component={RestaurantScreen}/>
</Stack.Navigator>
</NavigationContainer>
);
}
After first time onPress the MainScreen just reloads. After, the screens doesn't respond anything onPress to the cards. Also no error is shown up.
Related
I am building a to-do list app in react-native. I am a beginner to learn it. I had a function name handleSubmit() and a state data in the App.js file. I wanted to pass them as props in the respective components/screens.
Here's my try:
App.js
import React, { useState } from "react";
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import Welcome from './Screens/Welcome';
import Tasklist from './Screens/Tasklist';
import Addtask from './Screens/Addtask';
const Stack = createNativeStackNavigator();
export default function App() {
const [data,setData] = useState([]);
const handleSubmit = (task) => {
console.log("submit pressed")
setData((prevtodo)=> {
return [
{
task:task,
key: Math.random().toString(),
},
...prevtodo
];
});
}
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{header: ()=>null}}>
<Stack.Screen name='Welcome' component={Welcome}></Stack.Screen>
<Stack.Screen name='Tasklist' component={Tasklist} data={data}></Stack.Screen>
<Stack.Screen name='Addtask' component={Addtask} handleSubmit={handleSubmit}></Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
And in the component Addtask , I am using like this
import React, { useState } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import { StatusBar } from "expo-status-bar";
const Addtask = ({navigation, handleSubmit}) => {
console.log(handleSubmit)
const [task, setTask] = useState("");
return (
<View style={styles.container}>
<StatusBar style="light" backgroundColor="midnightblue" />
<View>
<Text style={styles.text}>Add Task Here</Text>
</View>
<View>
<TextInput
style={styles.input}
onChangeText={setTask}
value={task}
placeholder="Type your task"
keyboardType="ascii-capable"
/>
</View>
<View style={styles.buttoms}>
<View style={{margin:4}}>
<Button color={'red'} onPress={()=>{navigation.goBack()}} title="Cancel"></Button>
</View>
<View style={{margin:4}}>
<Button color={'lightblue'} onPress={()=>setTask('')} title="Clear"></Button>
</View>
<View style={{margin:4}}>
<Button color={'green'} onPress={handleSubmit} title="Save"></Button>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
.
.
.
.
});
export default Addtask;
On logging the handleSubmit() in the Addtask.js, I am getting undefined. How can I achieve the abovementioned thing?
You have to use initialParams here
<Stack.Screen
name="Details"
component={DetailsScreen}
initialParams={{ itemId: 42 }}
/>
you can refer the docs here https://reactnavigation.org/docs/params/#initial-params
P.S. passing a function in here might give a warning
Let me summarize a lil bit, what I'm trying to do is when the news is clicked, a modal (in this case I used a library: react-native-modalize https://github.com/jeremybarbet/react-native-modalize) is presented with the respective details of the clicked news
In order for the content inside the modal to be dynamic, I used states to store the details, so whenever a click is registered on the news, a series of details is passed thru function parameters and store in the respective state
THE PROBLEM is that whenever a state on the top level is changed the whole component refresh itself, and it's causing problem like:
Scenario 1: when the user scroll until the end of the scroll view and pressed on one of the news, modal is brought up and because the state is being changed, the whole app refreshes and the scroll view jumps back to the top.
app.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { useRef, useState, useEffect } from 'react';
import { AppLoading } from 'expo'
import { StyleSheet, Text, View, FlatList, SafeAreaView, ScrollView, Image, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { Modalize } from 'react-native-modalize';
import { Ionicons } from '#expo/vector-icons';
import { render } from 'react-dom';
import Header from './components/Header';
import NuaDaily from './components/Daily';
import Content from './components/Content';
import moment from "moment";
const HomeStackScreen = () => {
const [title, setTitle] = useState([])
const [author, setAuthor] = useState([])
const [publication, setPublication] = useState([])
const [imageUrl, setImageUrl] = useState([])
const [summary, setSummary] = useState([])
const modalizeRef = useRef(null);
const onOpen = (title, author, publication, imageUrl, summary) => {
modalizeRef.current?.open();
setTitle(title)
setAuthor(author)
setPublication(publication)
setImageUrl(imageUrl)
setSummary(summary)
};
return (
<>
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={styles.container}>
<Header />
<NuaDaily modalize={onOpen} style={styles.nuadaily} />
<Content modalize={onOpen} />
</View>
</ScrollView>
</SafeAreaView>
<Modalize snapPoint={650} modalTopOffset={10} ref={modalizeRef} style={{ width: '100%', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
<View style={{padding: 20}}>
<Image
style={{width: 350, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={styles.modalTitle}>{title}</Text>
<View style={styles.detailsBar}>
<Text style={styles.modalAuthor}>{author}</Text>
<Text style={styles.modalPublication}>{moment(publication).format("MM-DD-YYYY")}</Text>
</View>
<Text style={styles.modalSummary}>{summary}</Text>
</View>
</Modalize>
</>
)
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={
{
activeTintColor: '#00B2FF',
inactiveTintColor: 'gray',
showLabel: false,
style: { height: 60, borderRadius: 0, backgroundColor: 'rgba(255, 255, 255, 0.85)'}
}
}
showLabel = {false}
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
if (route.name === 'Home') {
return <HomeIcon />
}
},
})}
>
<Tab.Screen name="Home"
component={
HomeStackScreen
} />
</Tab.Navigator>
</NavigationContainer>
);
}
});
Daily (index.js) (imported on app.js)
import React from 'react';
import { useState, useEffect } from 'react';
import {View, Text, FlatList, Image, ImageBackground, ScrollView, SafeAreaView, TouchableOpacity} from 'react-native';
import axios from 'axios';
import moment from "moment";
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import styles from './style';
import Dot from '../../assets/images/dot.svg';
const nuaDaily = ( props ) => {
const Item = ({ title, author, publication, imageUrl, summary }) => (
<View style={styles.item}>
<TouchableOpacity onPress={()=>props.modalize(title, author, publication, imageUrl, summary)}>
<Image
style={{width: 210, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={ [styles.title, {fontFamily: 'Poppins'}]}>{title}</Text>
<View style={styles.bottomBar}>
<Text style={styles.author}>{author}</Text>
<Text style={styles.publication}>{moment(publication).format("MM-DD-YYYY hh:mm")}</Text>
</View>
</TouchableOpacity>
</View>
);
const renderItem = ({ item }) => {
if(moment(item.publication).isSame(moment(), 'day')){
return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}else{
// return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}
};
const [data, setData] = useState([])
useEffect(() => {
axios.get(APIURL)
.then((res) => {
setData(res.data)
})
.catch((err) => {
console.log(`error calling API ${err}`)
})
},[])
return (
<View style={styles.container}>
<View style={styles.containerTitle}>
<Dot style={styles.dot} />
<Text style={ [styles.PrimaryText , {fontFamily: 'Quicksand'}]}>NUA Daily</Text>
</View>
<FlatList
showsHorizontalScrollIndicator={false}
horizontal={true}
data={data}
renderItem={renderItem}
style={styles.flatList}
/>
</View>
)
}
export default nuaDaily;
Demo of the problem (Scenario 1)
The data being fetched from the api is needed for other purposes in the modal. How do i pass data: {currency.data.prices[index].instrument} {currency.data.prices[index].closeoutAsk} {currency.data.prices[index].closeoutBid} that is in a component to a modal that is in the same component. Below is the code:
//HomeScreen
import React, {useContext, useState} from 'react'
import { Text, View, ScrollView, TouchableOpacity, Modal, TextInput } from 'react-native'
import {ListItem, Card, Button, Icon} from 'react-native-elements'
//import CurrencyPair from '../../CurrencyPair'
import {firebase} from '../../../firebase/config'
import {CurrencyContext} from '../../../context/Context'
import styles from '../LoginScreen/styles'
function HomeScreen() {
const currency = useContext(CurrencyContext);
const [modalopen, setModalOpen] = useState(false)
return (
<ScrollView>
<Modal
visible={modalopen}
animationType={"fade"}
>
<View style={styles.modal}>
<View>
<Text style={{textAlign: "center", fontWeight: "bold"}}>
CreateAlert
</Text>
<TouchableOpacity style={styles.button} onPress={() => setModalOpen(false)}>
<Text style={styles.buttonTitle}>OK</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
<Card>
<Text style={{textAlign: "center"}}>
Welcome
</Text>
<Button title="Sign Out" type="outline" onPress ={() => firebase.auth().signOut()}/>
<Button title="My Alerts" onPress ={() =>navigation.navigate("AlertScreen") }/>
</Card>
<View>
{currency.data.prices && currency.data.prices.map((prices, index) => {
return (
<ListItem
key={index}
onPress = {() => setModalOpen(true)}
bottomDivider>
<ListItem.Content>
<ListItem.Title>
{currency.data.prices[index].instrument} {currency.data.prices[index].closeoutAsk} {currency.data.prices[index].closeoutBid}
</ListItem.Title>
</ListItem.Content>
</ListItem>
)
})
}
</View>
</ScrollView>
)
}
export default HomeScreen
//Context
import React, {createContext, useState, useEffect}from 'react'
import {ActivityIndicator} from 'react-native'
import axios from '../utils/axios'
const CurrencyContext = createContext();
const CurrencyProvider =(props) => {
const [data, setData] = useState([])
const [isLoading, setIsloading] = useState(true)
useEffect(() => {
const interval = setInterval(() => {
const fetchpairs = async() => {
const results = await axios.get('/v3/accounts/101-004-14328428-002/pricing?instruments=AUD_CAD%2CAUD_CHF%2CAUD_JPY%2CAUD_NZD%2CAUD_USD%2CCAD_CHF%2CCAD_JPY%2CCHF_JPY%2CEUR_AUD%2CEUR_CAD%2CEUR_CHF%2CEUR_GBP%2CEUR_NOK%2CEUR_NZD%2CEUR_USD%2CGBP_AUD%2CGBP_CAD%2CGBP_CHF%2CGBP_USD%2CGBP_JPY%2CNZD_CAD%2CNZD_CHF%2CNZD_JPY%2CUSD_CAD%2CUSD_JPY%2CUSD_CHF%2CUSD_ZAR%2CUSD_MXN')
setData(results.data)
setIsloading(false)
}
fetchpairs()
},1000)
}, []);
if(isLoading) {
return (
<ActivityIndicator size="large"/>
)
}else
return (
<CurrencyContext.Provider
value={{
data,
setData,
isLoading,
setIsloading
}}>
{props.children}
</CurrencyContext.Provider>
)
}
export {CurrencyProvider, CurrencyContext}
you can create another state variable to store the clicked index.
const [clickedIndex, setClickedIndex] = useState(0);
then use that in the onPress event.
onPress = {() => {setModalOpen(true);setClickedIndex(index);}
then you can use this same index to display what you want in the modal.
<Modal
visible={modalopen}
animationType={"fade"}
>
<View style={styles.modal}>
<View>
<Text style={{textAlign: "center", fontWeight: "bold"}}>
{currency.data.prices[clickedIndex].instrument}
</Text>
<TouchableOpacity style={styles.button} onPress={() => setModalOpen(false)}>
<Text style={styles.buttonTitle}>OK</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
So I am following Academind tutorial on youtube on react native but i can't seem to get to work the passing of values between tow components.
In startgamescreen on this line onPress={()=>props.onGame(selNumber)} I seem to follow him and pass selNumber but the error I get is onGame is not a function and undefined
and in App.js
const gameHandler=(selNum)=>{
setUserNumber(selNum);
};
let content=<StartGameScreen onGame={gameHandler} />;
Here I seem to exactly follow him and pass the gamehandler but I still don't get what went wrong. Please help me I have tried to debug this code for a while now.
StartGameScreen.js
import React, {useState} from 'react';
import { View, StyleSheet, Alert ,Text, Button, TouchableWithoutFeedback,Keyboard} from 'react-native';
import NumberComponents from '../components/NumberComponent';
import Card from '../components/Card';
import Colors from '../constants/colors';
import Input from '../components/Input';
const StartGameScreen = props => {
const [enteredValue,setEnteredValue]=useState('');
const [confirmed,setConfirmed]=useState(false);
const [selNumber,setSelNumber]=useState('');
const numberHandler =textinput=>{
setEnteredValue(textinput.replace(/[^0-9]/g,''));
};
let confirmedOutput;
if(confirmed){
confirmedOutput=<Card style={styles.confirm}>
<Text>You Selected:</Text>
<NumberComponents children={selNumber}/>
<Button title='Start Game' onPress={()=>props.onGame(selNumber)}/>
</Card>
}
const resetInputHandler=()=>{
setEnteredValue('');
setConfirmed(false);
};
const confirmButtonHandler=()=>{
const chosenNum=parseInt(enteredValue);
if(isNaN(chosenNum) || chosenNum<=0 || chosenNum>99){
Alert.alert(
'InValid Number',
'Please Enter Valid Number Between 1 and 99',
[{text:'Okay',style:'destructive',onPress:resetInputHandler}]
)
return;
}
setConfirmed(true);
setEnteredValue('');
setSelNumber(chosenNum);
Keyboard.dismiss();
};
return (
<TouchableWithoutFeedback onPress={()=>{Keyboard.dismiss();}}>
<View style={styles.screen}>
<Text style={styles.title}> Start A New Game </Text>
<Card style={styles.inputContainer}>
<Text style={{ color: 'green', fontSize: 15 }}>Choose A Number</Text>
<Input
keyboardType='number-pad'
maxLength={2}
style={styles.input}
blurOnSubmit
onChangeText={numberHandler}
value={enteredValue}
/>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button
title='Reset'
color={Colors.accent}
onPress={resetInputHandler} />
</View>
<View style={styles.button}>
<Button
title='Confirm'
onPress={confirmButtonHandler}
color='orange' />
</View>
</View>
</Card>
{confirmedOutput}
</View>
</TouchableWithoutFeedback>
);
};
in App.js
import React,{ useState } from 'react';
import { StyleSheet, View } from 'react-native';
import Header from './components/Header';
import StartGameScreen from './screens/StartGameScreen';
import GameScreen from './screens/StartGameScreen';
export default function App() {
const [userNumber,setUserNumber]=useState();
const gameHandler=(selNum)=>{
setUserNumber(selNum);
};
let content=<StartGameScreen onGame={gameHandler} />;
if(userNumber){
content=<GameScreen userChoice={userNumber}/>;
}
return (
<View style={styles.screen}>
<Header title="Guess A Number"/>
{content}
</View>
);
}
const styles = StyleSheet.create({
screen:{
flex:1,
}
});
You need to add onGame={gameHandler} into this component:
if (userNumber) {
content = <GameScreen onGame={gameHandler} userChoice={userNumber} />;
}
Since GameScreen and StartGameScreen are the same components,
import StartGameScreen from './screens/StartGameScreen';
import GameScreen from './screens/StartGameScreen';
in the second case when userNumber is not false the GameScreen component was called without the onGame props.
See the working stripped down version in codesandbox:
https://codesandbox.io/s/affectionate-wright-3bccd
Hello if there are not parent-child relation between your components,you can use Event like DeviceEventEmitter.
Here is a good link for example: [https://callstack.com/blog/sending-events-to-javascript-from-your-native-module-in-react-native/][1]
I'm the newbie of the react-native and study with the complete code. But I can't understand the diffrence between "const" before export and after render. for example:
const { height, width } = Dimensions.get("window");
export default class App extends React.Component {
state = {
newToDo: ""
};
render() {
const { newToDo } = this.state;
why I ask this is because my first init is not "export default class App extends React.Component {" but "export default function App() {". So I can't assign const or assign it and it cause the Error showing the message
TypeError:undefined is not an object (evaluating 'this.state')
this is my code :
import React from "react";
import {
StyleSheet,
Text,
View,
Dimensions,
TextInput,
Platform,
ScrollView
} from "react-native";
import ToDo from "./ToDo";
const { height, width } = Dimensions.get("window");
export default function App() {
const state = {
newToDo: ""
};
const { newToDO } = this.state;
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Good or Bad</Text>
<Text style={styles.subTitle}>Check Daily your habit</Text>
</View>
<View style={styles.content}>
<Text style={styles.contentTitle}>To Do List</Text>
<TextInput
style={styles.input}
placeholder={"New to do"}
value={newToDO}
onChangeText={this._controllNewToDo}
returnKeyType={"done"}
autoCorrect={false}
/>
<ScrollView>
<ToDo />
</ScrollView>
</View>
</View>
);
_controllNewToDo = text => {
this.setState({
newToDO: text
});
};
}
You can't use this.setState({}) inside a functional components. So you should use a normal class component to be able to call this.setState or use Hooks to update state inside functionals components.
import React, {Component} from "react";
import {
StyleSheet,
Text,
View,
Dimensions,
TextInput,
Platform,
ScrollView
} from "react-native";
import ToDo from "./ToDo";
const { height, width } = Dimensions.get("window");
class App extends Component {
state = {
newToDo: ""
};
_controllNewToDo = text => {
this.setState({
newToDO: text
});
};
render(){
const { newToDO } = this.state;
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Good or Bad</Text>
<Text style={styles.subTitle}>Check Daily your habit</Text>
</View>
<View style={styles.content}>
<Text style={styles.contentTitle}>To Do List</Text>
<TextInput
style={styles.input}
placeholder={"New to do"}
value={newToDO}
onChangeText={this._controllNewToDo}
returnKeyType={"done"}
autoCorrect={false}
/>
<ScrollView>
<ToDo />
</ScrollView>
</View>
</View>
);
}
}
export default App;
Try this code!
As i mentioned below, If you need to use state and setState({}) you should use inside class components. otherwise you should use Hooks, check this .I think this will help you to understand.
import React from 'react';
import {
StyleSheet,
Text,
View,
Dimensions,
TextInput,
Platform,
ScrollView,
} from 'react-native';
const { height, width } = Dimensions.get('window');
export default class App extends React.Component {
state = {
newToDo: 'wwe',
};
_controllNewToDo = text => {
this.setState({
newToDO: text,
});
};
render() {
const { newToDO } = this.state;
return (
<View>
<View>
<Text>Good or Bad</Text>
<Text>Check Daily your habit</Text>
</View>
<View>
<Text>To Do List</Text>
<TextInput
style={{ height: 60 }}
placeholder={'New to do'}
value={newToDO}
onChangeText={this._controllNewToDo}
returnKeyType={'done'}
autoCorrect={false}
/>
<ScrollView
style={{ justifyContent: 'center', alignItems: 'center' }}>
<Text>{newToDO}</Text>
</ScrollView>
</View>
</View>
);
}
}
Feel free for doubts
In functional component you have use useState hook to manage state.Try this,
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Dimensions,
TextInput,
Platform,
ScrollView
} from "react-native";
import ToDo from "./ToDo";
const { height, width } = Dimensions.get("window");
export default function App() {
const [newToDo, setNewToDo] = useState("");
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Good or Bad</Text>
<Text style={styles.subTitle}>Check Daily your habit</Text>
</View>
<View style={styles.content}>
<Text style={styles.contentTitle}>To Do List</Text>
<TextInput
style={styles.input}
placeholder={"New to do"}
value={newToDo}
onChangeText={_controllNewToDo}
returnKeyType={"done"}
autoCorrect={false}
/>
<ScrollView>
<ToDo />
</ScrollView>
</View>
</View>
);
const _controllNewToDo = text => {
setNewToDo(text);
};
}