react native hover effect module not working properly in dynamic - javascript

I trying to make a onPress hover effect to show text, when I click on image it will show me a text layer on my image, as its working fine for one image & text, but while making dynamic.. clicked on one image then that effect, affecting to all images with text.
simply I want to show on single click show one text related to img, on different images on click show different text related to that images.
how can fix it..
App.js
import Button from "../custom-components/Button";
import React, { useState, useEffect } from "react";
import {
Image,
ImageBackground,
StyleSheet,
TouchableOpacity,
Text,
Touchable,
View,
FlatList,
} from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { BottomTabBarHeightCallbackContext } from "#react-navigation/bottom-tabs";
import axios from "axios";
import { API_URL } from "#env";
import { useSelector } from "react-redux";
export default function App() {
const languageState = useSelector((state) => state.languageReducer);
const [xx43d, setxx43d] = React.useState(languageState.language);
const [showText, setShowText] = useState(false);
const [apiData, setApiData] = useState([]);
React.useEffect(() => {
axios
.get(`${API_URL}/xyxsnn?xx43d=${xx43d}`)
.then((response) => {
if (response.status === 200) {
setApiData(response.data.result);
}
})
.catch((errors) => {
console.log(errors);
});
}, []);
return (
<>
<ScrollView>
<FlatList
data={apiData}
numColumns={2}
keyExtractor={(item, index) => index}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.5}
onPress={() => setShowText(!showText)}
>
<ImageBackground
source={{ uri: "https://reactjs.org/logo-og.png" }}
resizeMode="cover"
style={styles.image}
>
{!!showText && <Text style={styles.text}>{item.name}</Text>}
</ImageBackground>
</TouchableOpacity>
</>
)}
/>
</ScrollView>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
justifyContent: "center",
height: 250,
width: 170,
margin: 12,
borderRadius: 10,
},
text: {
color: "white",
fontSize: 20,
fontWeight: "bold",
textAlign: "center",
backgroundColor: "#000",
},
});

Make Item a seprate component which has its own showText state.
Like
import Button from "../custom-components/Button";
import React, { useState, useEffect } from "react";
import {
Image,
ImageBackground,
StyleSheet,
TouchableOpacity,
Text,
Touchable,
View,
FlatList,
} from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { BottomTabBarHeightCallbackContext } from "#react-navigation/bottom-tabs";
import axios from "axios";
import { API_URL } from "#env";
import { useSelector } from "react-redux";
export default function App() {
const languageState = useSelector((state) => state.languageReducer);
const [xx43d, setxx43d] = React.useState(languageState.language);
const [apiData, setApiData] = useState([]);
React.useEffect(() => {
axios
.get(`${API_URL}/xyxsnn?xx43d=${xx43d}`)
.then((response) => {
if (response.status === 200) {
setApiData(response.data.result);
}
})
.catch((errors) => {
console.log(errors);
});
}, []);
return (
<>
<ScrollView>
<FlatList
data={apiData}
numColumns={2}
renderItem={({ item }) => <Item data={item}/>}
keyExtractor={(item, index) => index}
/>
</ScrollView>
</>
);
}
const Item = ({data}) => {
const [showText, setShowText] = useState(false);
return(<TouchableOpacity
activeOpacity={0.5}
onPress={() => setShowText(!showText)}
>
<ImageBackground
source={{ uri: "https://reactjs.org/logo-og.png" }}
resizeMode="cover"
style={styles.image}
>
{showText && <Text style={styles.text}>{data.name}</Text>}
</ImageBackground>
</TouchableOpacity>)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
justifyContent: "center",
height: 250,
width: 170,
margin: 12,
borderRadius: 10,
},
text: {
color: "white",
fontSize: 20,
fontWeight: "bold",
textAlign: "center",
backgroundColor: "#000",
},
});

Related

React Native, passing data between screens when using BottomTabsNavigator

I am trying to make a react native application. I am using Bottom Tab Navigation, and I have 2 screens. On the first screen, a qr code is first scanned, it contains a string, which is written on the screen.
Then I would like to write out the afformentioned string on the second tab.
How can I pass this data between the screens of the Bottom Tab Navigator?
App:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import QrcodeScreen from './src/screens/QrcodeScreen';
import EttermekScreen from './src/screens/EttermekScreen';
const Tab =createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name='Qrcode' component={QrcodeScreen} />
<Tab.Screen name='Ettermek' component={EttermekScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
QrcodeScreen:
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
export default function QrcodeScreen() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [text, setText] = useState('Not yet scanned')
const askForCameraPermission = () => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})()
}
// Request Camera Permission
useEffect(() => {
askForCameraPermission();
}, []);
// What happens when we scan the bar code
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setText(data)
console.log('Type: ' + type + '\nData: ' + data)
};
// Check permissions and return the screens
if (hasPermission === null) {
return (
<View style={styles.container}>
<Text>Requesting for camera permission</Text>
</View>)
}
if (hasPermission === false) {
return (
<View style={styles.container}>
<Text style={{ margin: 10 }}>No access to camera</Text>
<Button title={'Allow Camera'} onPress={() => askForCameraPermission()} />
</View>)
}
// Return the View
return (
<View style={styles.container}>
<View style={styles.barcodebox}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ height: 400, width: 400 }} />
</View>
<Text style={styles.maintext}>{text}</Text>
{scanned && <Button title={'Scan again?'} onPress={() => setScanned(false)} color='tomato' />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
maintext: {
fontSize: 16,
margin: 20,
},
barcodebox: {
alignItems: 'center',
justifyContent: 'center',
height: 300,
width: 300,
overflow: 'hidden',
borderRadius: 30,
backgroundColor: 'tomato'
}
});
The screen I would like to print the string:
import { StyleSheet, Text, View } from 'react-native';
import React from 'react';
import { StatusBar } from 'expo-status-bar';
import QrcodeScreen from './QrcodeScreen';
export default function EttermekScreen({ route }) {
const { varisId } = route.params
return (
<View style={styles.container}>
<Text>ÉTTERMEK</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
In EttermekScreen, you already have this line, const { varisId } = route.params, and grabbing from the props route, so you should be good with it.
Assuming you wanna send data in handleBarCodeScanned to EttermekScreen as a parameter called varisId, you could do it this way:
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
export default function QrcodeScreen({navigation}) {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [text, setText] = useState('Not yet scanned')
const askForCameraPermission = () => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})()
}
// Request Camera Permission
useEffect(() => {
askForCameraPermission();
}, []);
// What happens when we scan the bar code
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setText(data);
navigation.navigate('Ettermek', {
varisId: data
});
};
// Check permissions and return the screens
if (hasPermission === null) {
return (
<View style={styles.container}>
<Text>Requesting for camera permission</Text>
</View>)
}
if (hasPermission === false) {
return (
<View style={styles.container}>
<Text style={{ margin: 10 }}>No access to camera</Text>
<Button title={'Allow Camera'} onPress={() => askForCameraPermission()} />
</View>)
}
// Return the View
return (
<View style={styles.container}>
<View style={styles.barcodebox}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ height: 400, width: 400 }} />
</View>
<Text style={styles.maintext}>{text}</Text>
{scanned && <Button title={'Scan again?'} onPress={() => setScanned(false)} color='tomato' />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
maintext: {
fontSize: 16,
margin: 20,
},
barcodebox: {
alignItems: 'center',
justifyContent: 'center',
height: 300,
width: 300,
overflow: 'hidden',
borderRadius: 30,
backgroundColor: 'tomato'
}
});

delete list element using filter method

I am working on todo list in native , i have a function called onDelete but when i click on it , it delete all element in list and after then program crashed.
this is my main file where i have stored value as key , value pair
export default function App() {
const [courseGoal, setCourseGoal] = useState([]);
const [count, setCount] = useState('');
const submitHandler = () => {
setCourseGoal((currGoal) => [
...currGoal,
{ key: Math.random().toString(), value: count },
]);
};
console.log('App', courseGoal)
return (
<View style={styles.container}>
<SearchBar
setCourseGoal={setCourseGoal}
count={count}
setCount={setCount}
submitHandler={submitHandler}
/>
<ListItem courseGoal={courseGoal} setCourseGoal={setCourseGoal} courseGoal={courseGoal}/>
</View>
);
}
this is my list component where i am facing issue, you can see ondelete here.
import React from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";
import { FlatList } from "react-native-web";
export default function ListItem(props) {
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
currGoal.filter((goal) => goal.key !== goalId);
console.log("clicked", props.courseGoal[0].key);
});
};
return (
<FlatList
data={props.courseGoal}
keyExtractor={(item, index) => item.key}
renderItem={(itemData) => (
<TouchableOpacity
onPress={onDelete.bind(itemData.item.key)}
activeOpacity={0.2}
>
<Text style={styles.listData}>{itemData.item.value}</Text>
{console.log(itemData.item.key)}
</TouchableOpacity>
)}
/>
);
}
this is my main component where i have my search input
import React from "react";
import { View, Text, StyleSheet, Pressable, TextInput } from "react-native";
export default function SearchBar(props) {
const onInputHandler = (value) => {
props.setCount(value);
};
return (
<View style={styles.searchBox}>
<Pressable style={styles.submitBtn} title="Click Me !">
<Text>☀️</Text>
</Pressable>
<TextInput
style={styles.searchInput}
placeholder="Enter Goal"
onChangeText={onInputHandler}
/>
<Pressable
style={styles.submitBtn}
title="Click Me !"
onPress={props.submitHandler}
>
<Text>🔥🔥</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
searchBox: {
flexDirection: "row",
justifyContent: "space-around",
},
searchInput: {
width: "90%",
textAlign: "center",
padding: 10,
// color: 'white',
borderRadius: 10,
borderWidth: 1,
marginHorizontal: 5,
},
submitBtn: {
color: "black",
justifyContent: "space-around",
padding: 10,
borderRadius: 10,
borderWidth: 1,
},
});
You have to return the filtered array from your onDelete function
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
return currGoal.filter((goal) => goal.key !== goalId);
});
};

Ways to stop re-rendering when a state is changed ? (React Native)

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)

Unable to navigate to next screen in React Native

I have created a list of posts and want to pass details of one specfic post to another screen. I want to be able to click on the post and be directed to the post details screen. This is the PostList.js file:
import React, {Component} from 'react';
import {
FlatList,
StyleSheet,
View,
Text,
Modal,
TouchableOpacity,
} from 'react-native';
import Post from './Post';
import Firebase from 'firebase';
import 'firebase/database';
import {firebaseConfig} from './configFirebase';
import PostDetails from './stack/PostDetails';
export default class Posts extends Component {
constructor(props) {
super(props);
!Firebase.apps.length
? Firebase.initializeApp(firebaseConfig.firebase)
: Firebase.app();
this.state = {
postList: [],
navigation: this.props.navigation,
};
}
state = {
loading: false,
currentPost: null,
};
componentDidMount() {
this.getPostData();
}
getPostData = () => {
const ref = Firebase.database().ref('/posts');
ref.on('value', snapshot => {
console.log('DATA RETRIEVED');
const postsObject = snapshot.val();
if (!postsObject) {
return console.warn('No data from firebase');
}
const postsArray = Object.values(postsObject);
this.setState({postList: postsArray});
});
};
render() {
return (
<View style={styles.container}>
<FlatList
keyExtractor={post => post.heading}
data={this.state.postList}
renderItem={({item: post}) => (
<Post
key={post.heading}
heading={post.heading}
description={post.description}
location={post.location}
onPress={() => this.props.navigation.push('PostDetails', {post})}
/>
)}
/>
</View>
);
}
}
export const styles = StyleSheet.create({
container: {
borderWidth: 2,
borderRadius: 5,
backgroundColor: '#2bb76e',
flex: 1,
},
txtInput: {
flex: 1,
margin: 5,
padding: 5,
borderWidth: 2,
fontSize: 20,
borderRadius: 5,
backgroundColor: 'snow',
},
});
I've tried navigation.navigate() and navigation.push() and neither work.
This is the PostDetails Screen I want to navigate to and pass the post info to:
import React from 'react';
import {Text, View} from 'react-native';
export default ({route}) => {
const postInfo = route.params.post;
return (
<View>
<Text>{JSON.stringify(postInfo, null, 2)}</Text>
<Text>{postInfo.heading}</Text>
</View>
);
};
This is my HomeStack file where the screens are kept:
import React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import Posts from '../PostList';
import AddForm from '../AddForm';
import PostDetails from './PostDetails';
const HomeStack = createStackNavigator();
const HomeStackScreen = () => (
<HomeStack.Navigator>
<HomeStack.Screen
name="PostList"
component={Posts}
options={{headerTitle: 'big APPetite'}}
/>
<HomeStack.Screen
name="PostDetails"
component={PostDetails}
options={({route}) => ({heading: route.params.post.heading})}
/>
<HomeStack.Screen name="NewPost" component={AddForm} />
</HomeStack.Navigator>
);
export default HomeStackScreen;
Post.js:
import React, {Component} from 'react';
import {
Image,
Text,
StyleSheet,
View,
TextInput,
FlatList,
TouchableOpacity,
} from 'react-native';
import FavouriteButton from './buttons/FavouriteButton';
import chickenClub from './images/chickenSandwich.jpg';
const Post = ({heading, description, location, username}) => (
<TouchableOpacity style={postStyle.container}>
<View style={(postStyle.container, {alignItems: 'flex-start'})}>
<View style={postStyle.padding}>
<Image style={postStyle.image} source={chickenClub} />
<View style={{backgroundColor: (255, 255, 255, 45), borderRadius: 6}}>
<Text style={postStyle.text}>{heading}</Text>
<Text style={postStyle.text}>{location}</Text>
<Text style={postStyle.text}>{username}*username*</Text>
</View>
</View>
<View
style={{
alignSelf: 'flex-end',
flexDirection: 'column',
backgroundColor: '#2bb76e',
}}>
<Text style={postStyle.paragraph}>{description}</Text>
<View style={{justifyContent: 'flex-start', alignItems: 'flex-end'}}>
<FavouriteButton />
</View>
</View>
</View>
</TouchableOpacity>
);
const postStyle = StyleSheet.create({
container: {
borderWidth: 2,
borderRadius: 5,
backgroundColor: '#2bb76e',
flex: 1,
},
padding: {
padding: 10,
},
heading: {
backgroundColor: (255, 250, 250, 50),
flexDirection: 'column',
},
paragraph: {
alignSelf: 'flex-end',
fontSize: 20,
},
username: {},
image: {
flexDirection: 'row',
height: 150,
width: 150,
},
text: {
fontSize: 25,
padding: 5,
},
});
export default Post;
You are passing onPress to your Post component, however you are not applying that prop to the TouchableOpacity.
Modifying the Post component to include:
const Post = ({heading, description, location, username, onPress}) => (
<TouchableOpacity style={postStyle.container} onPress={onPress}>

React Native Delete Function not working as intended

The intended function is that it would just delete the one goal that is clicked but for some odd reason it decides onPress to delete all goals listed.
I am following this tutorial https://www.youtube.com/watch?v=qSRrxpdMpVc and im stuck around 2:44:45. If anyone else has done this tutorial and or can see my problem an explanation would be greatly appreciated. :)
Program
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Button,
TextInput,
ScrollView,
FlatList
} from "react-native";
import GoalItem from "./components/GoalItem";
import GoalInput from "./components/GoalInput";
export default function App() {
const [courseGoals, setCourseGoals] = useState([]);
const addGoalHandler = goalTitle => {
setCourseGoals(currentGoals => [
...currentGoals,
{ key: Math.random().toString(), value: goalTitle }
]);
};
const removeGoalHander = goalId => {
setCourseGoals(currentGoals => {
return currentGoals.filter((goal) => goal.id !== goalId);
});
};
return (
<View style={styles.screen}>
<GoalInput onAddGoal={addGoalHandler} />
<FlatList
keyExtractor={(item, index) => item.id}
data={courseGoals}
renderItem={itemData => (
<GoalItem
id={itemData.item.id}
onDelete={removeGoalHander}
title={itemData.item.value}
/>
)}
></FlatList>
</View>
);
}
const styles = StyleSheet.create({
screen: {
padding: 80
}
});
Function
import React from "react";
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
const GoalItem = props => {
return (
<TouchableOpacity onPress={props.onDelete.bind(this, props.id)}>
<View style={styles.listItem}>
<Text>{props.title}</Text>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
listItem: {
padding: 10,
backgroundColor: "lightgrey",
borderColor: "grey",
borderRadius: 5,
borderWidth: 1,
marginVertical: 10
}
});
export default GoalItem;
When updating state, you have to pass new array so component can detect changes and update view
const removeGoalHander = goalId => {
setCourseGoals(currentGoals => {
const newGoals = currentGoals.filter((goal) => goal.id !== goalId);
return [...newGoals];
});
};

Categories

Resources