Passing a local variable to a component in React Native - javascript

I am building a todo list app, and I want to long press individual todos, to change their color to green in order to mark them as finished.
I have a var color = 'white'; inside my App.js and I have another component named listItem for the list items.
I have this pretty basic function to change the color
const longPressHandler = () => {
(color == 'white') ? color = 'green' : color = 'white';
}
and I am sending the color via props of listItem
<ListItem item={item} longPressHandler = {longPressHandler} color={color} pressHandler = {pressHandler}/>
and I am using it as follows backgroundColor: props.color Check below:
const styles = StyleSheet.create({
listItem:{
padding: 8,
margin:4,
fontSize: 18,
textAlignVertical:'center',
borderColor:'gray',
borderWidth: 3,
borderStyle: 'solid',
borderRadius:10,
backgroundColor: props.color,
}
})
BUUT, it does not work... What am i doing wrong? Is there any simple solution that I am missing...
Here is the full code of App.js
import React, {useEffect, useState} from 'react';
import {Text, View, StyleSheet, FlatList, Alert, TouchableWithoutFeedback, Keyboard, Button, AsyncStorage } from 'react-native';
import ListItem from './components/listItem';
import AddItem from './components/addItem';
// npx react-native start // TO START
// npx react-native run-android // TO PROJECT INTO EMULATOR
//Hooks cant be used in class components, thus, switched from Class component structure => Function component structure
export default function TODOList() {
const [todos, setTodos] = useState([
{todo: 'do chores', key: '1'},
{todo: 'do homework', key: '2'},
{todo: 'go to grocery', key: '3'},
]);
var color = 'white';
//This handler DELETES the pressed list item from the list
const pressHandler = (key) => {
const newtodos = todos.filter(todo => todo.key != key);
setTodos(newtodos);
}
//ADDS a new todo with the given text and a randomly generated key to the old todos list
const inputSubmitHandler = (text) => {
if(text.length > 0){
const key = Math.random().toString();
const newTodos = [{text, key}, ...todos];
setTodos(newTodos);
}else{
Alert.alert('ERROR!', 'Text cannot be empty', [{text:'OK'}])
}
}
//TODO Change color of the individual item in the list
const longPressHandler = () => {
(color == 'white') ? color = 'green' : color = 'white';
}
console.log('color', color);
return (
<TouchableWithoutFeedback onPress={() => {Keyboard.dismiss();}}>
<View style={styles.mainPage}>
<View style = {styles.header}>
<Text style={styles.title}>TODO List</Text>
</View>
<View style={styles.content}>
<AddItem inputSubmitHandler={inputSubmitHandler} />
<View style={styles.list}>
<FlatList
data={todos}
renderItem={( {item} ) => (
<ListItem item={item} longPressHandler = {longPressHandler} color={color} pressHandler = {pressHandler}/>
)}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>
);
}
//The margins, paddings, etc. are given as pixel values, wont work same in other devices.
const styles = StyleSheet.create({
mainPage: {
flex: 1, // takes the whole background
backgroundColor: 'white',
},
content: {
flex: 1,
},
list:{
margin: 10,
flex:1,
},
header:{
height: 50,
paddingTop: 8,
backgroundColor: 'orange'
},
title:{
textAlign: 'center',
fontSize: 24,
fontWeight: 'bold',
},
});
Here is the full code of listItem.js
import React from 'react';
import {Text, View, StyleSheet, TouchableOpacity} from 'react-native';
export default function ListItem(props) {
//Moved the style inside of the function since I want to use the color prop in 'backgroundCcolor'
const styles = StyleSheet.create({
listItem:{
padding: 8,
margin:4,
fontSize: 18,
textAlignVertical:'center',
borderColor:'gray',
borderWidth: 3,
borderStyle: 'solid',
borderRadius:10,
backgroundColor: props.color,
}
})
return (
<TouchableOpacity onLongPress={() => props.longPressHandler()} onPress = {() => props.pressHandler(props.item.key)}>
<Text style={styles.listItem}> {props.item.todo}</Text>
</TouchableOpacity>
)
}

There are few changes you can do to the code
Move the color choice to the ListItem and pass a prop to decide that
No need to create the whole style inside the item itself you can pass the ones that you want to override
So to do this you will have to start with your listitem
<TouchableOpacity
onLongPress={() => props.longPressHandler(props.item.key)}
onPress={() => props.pressHandler(props.item.key)}>
<Text
style={[
// this will make sure that only one style object is created
styles.listItem,
{ backgroundColor: props.marked ? 'green' : 'white' },
]}>
{props.item.todo}
</Text>
</TouchableOpacity>
And your long press handler should change like below, this will set the marked property in the state which you use to decide the color above
const longPressHandler = (key) => {
const updatedTodos = [...todos];
const item = updatedTodos.find((x) => x.key == key);
item.marked = !item.marked;
setTodos(updatedTodos);
};
You can refer the below snack
https://snack.expo.io/#guruparan/todo

Try this way
const longPressHandler = (index) => {
const newTodos = [...todos];
newTodos[index].color = (newTodos[index].color && newTodos[index].color == 'green') ? 'white' : 'green';
setTodos(newTodos);
}
<FlatList
data={todos}
renderItem={( {item, index} ) => (
<ListItem
item={item}
index={index}
longPressHandler = {longPressHandler}
color={item.color || 'white'}
pressHandler = {pressHandler}
/>
)}
/>
export default function ListItem(props) {
return (
<TouchableOpacity onLongPress={() => props.longPressHandler(props.index)} >
.....
</TouchableOpacity>
)
}
Note: You have to pass an index from renderItem to ListItem and also from ListItem to longPressHandler function

Related

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);
});
};

React Native - unable to pass state variable into style

My code fetches a json file, calculates a value and I want to pass this value into the style of TouchableOpacity. Below is my attempt:
const [height, setHeight] = useState(0)
const [isLoading, setLoader] = useState(true)
const fetching = async () => {
...//code that fetches the value
setHeight(value)
setLoader(false)
}
if (isLoading) {
return (
<Text> Loading...</Text>
)
}
return (
<View>
<TouchableOpacity
style={{height: height, width:30, backgroundColor: "red" }} />
... //other parts of the return statement
</View>
)
the complete code:
<View style={{height: height}}>
<TouchableOpacity
style={{width:30, borderWidth:5, marginTop:20, backgroundColor:"blue", height:height}}>
</TouchableOpacity>
</View>
Any help would be appreciated.
I think your useState is fine. However either the parent View doesn't have any space or the TouchableOpacity has nothing to display.
You can try to do:
return (
<View>
<TouchableOpacity
style={{height, width:30, borderWidth: 5 }} />
... //other parts of the return statement
</View>
)
If you see no border, then it's a problem with the parent View
You can then try:
return (
<View style={{flex: 1}}>
<TouchableOpacity
style={{height, width:30, borderWidth: 5 }} />
... //other parts of the return statement
</View>
)
You could also try adding a Text component with some text to the TouchableOpacity.
This code:
import React, { useEffect, useState } from 'react';
import {Text, View, TouchableOpacity} from 'react-native';
export default function App() {
const [height, setHeight] = useState(0)
const [isLoading, setLoader] = useState(true)
useEffect(() => {
const timerTask = setInterval(() => {
setHeight(Math.random() * 200)
setLoader(false);
}, 5000);
return () => clearInterval(timerTask);
}, [])
if (isLoading) {
return (
<Text> Loading...</Text>
)
}
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity
style={{width: 30, borderWidth: 5, marginTop: 20, backgroundColor: "blue", height}}>
</TouchableOpacity>
</View>
)
}
Produces a blue touchable opacity that changes height every 5 seconds. Also when I touch it, it turns a lighter shade.
It seems to me you might not be passing the style property in the render function of TouchableOpacity, TouchableOpacity is your own custom component, isn't it?
const TouchableOpacity = ({ style }) => {
...
return (
<div style={style} >
...
</div>
);
}
Add a height and width to your element's style
height: 50,
width: '100%',
backgroundColor: "#000000"

New to react native, Buttons don't seem to work individually

I'm trying to get each button to activate and "switch-on" when pressed, and I've used some documentation to help me. However, now it is not switching on.
Code Adds Switches in a FlatList
The Data should look like this:
https://imgur.com/a/761PSjre
Also, feel free to judge my code to the darkest depths of hell. I'm trying to improve my code.
import React from 'react'
import {StyleSheet, View,Text, Switch, Button, Alert, ScrollView, FlatList, SafeAreaView} from 'react-native'
export default () => {
const DATA = [
{
index: 1,
title: 'Toggle Night Mode',
},
{
index: 2,
title: 'Remind me to take a break',
},
{
index: 3,
title: "Remind me when it's bedtime",
},
];
const [enabledSwitches, setEnabledSwitches] = React.useState(DATA.length);
const toggleSwitch = () => setEnabledSwitches(previousState => !previousState);
function Item({title, index}) {
return (
<View>
<Text style={styles.text}> {title} </Text>
<Switch
trackColor={{ false: "#767577", true: "#81b0ff" }}
thumbColor="#f5dd4b"
ios_backgroundColor="#3e3e3e"
value={enabledSwitches[index]}
onValueChange={() => toggleSwitch(switches => {
switches[index] = !switches[index];
return switches;
})}
/>
</View>
)
}
function Header(){
return(
<View style = {styles.header}>
<Text style={styles.headertext}>Settings</Text>
</View>
)
}
return (
<>
<View style = {styles.container}>
<FlatList
data = {DATA}
keyExtractor = {item => item.id}
renderItem = {({ item, index }) => <Item title={item.title} index={index} /> }
ListHeaderComponent = {Header()}
/>
</View>
<View>
<Button
title = "Clear Search History"
color = "#6fb6f0"
onPress = {() => Alert.alert('Food History Has Been Cleared!')}
/>
</View>
<View>
<Button
title = "Logout"
color = "#6fb6f0"
onPress = {() => Alert.alert('Successfully Logged Out!')}
/>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 20,
fontWeight: "300"
},
headertext: {
fontSize: 30,
fontWeight: "300"
},
header:{
flex:1,
justifyContent: 'center',
alignItems: 'center',
padding: 10,
backgroundColor: '#f5f5f5'
}
})
Try this way
import React from 'react'
import {StyleSheet, View,Text, Switch, Button, Alert, ScrollView, FlatList, SafeAreaView} from 'react-native'
export default () => {
// use data set in default state
const [data, setData] = React.useState([ {index: 1,title: 'Toggle Night Mode'},...]);
function toggleSwitch(value, index){
const newData = [...data];
const newData[index].isEnable = value;
setData(newData);
}
function Item({item, index}) {
return (
<View>
<Text style={styles.text}> {item.title} </Text> // use `title` here like this
<Switch
.....
value={item.isEnable || false} // change here
onValueChange={(value) => toggleSwitch(value, index) } // change here
/>
</View>
)
}
return (
<>
<View style = {styles.container}>
<FlatList
data = {data}
keyExtractor = {item => item.id}
renderItem = {({ item, index }) => <Item item={item} index={index} /> } // send `item` as prop
/>
</View>
</>
);
}

How to send value from one tab to another tab in react native

Here in my code I am making tree tabs , on first tabe there are two input fields and buttons.
Now after entering the value in input and on button click i have to send vale to oter tabs.
Like in in name field I am entering name "Abhi" and on button click this Abhi should reflect on Tab 2.
Same like in Animal field , this Animal should reflect on third tab .
Please help
import * as React from 'react';
import { View, StyleSheet, Dimensions,Text,TextInput,TouchableOpacity } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View style={[styles.scene, { backgroundColor: '#FFFFFF' }]} >
<View style={{}}>
<Text style={{margin:15}}>Name </Text>
<TextInput style={styles.input}
underlineColorAndroid = "transparent"
placeholder = "Name"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
onChangeText={text => onChangeText(text)}
/>
<TouchableOpacity
style = {styles.submitButton}
onPress = {
() => this.Name()
}>
<Text style = {styles.submitButtonText}> Submit </Text>
</TouchableOpacity>
</View>
<View style={{}}>
<Text style={{margin:15}}> Favorite Animal </Text>
<TextInput style={styles.input}
underlineColorAndroid = "transparent"
placeholder = "Favorite Animal"
placeholderTextColor = "#9a73ef"
autoCapitalize = "none"
onChangeText={text => onChangeText(text)}
/>
<TouchableOpacity
style = {styles.submitButton}
onPress = {
() => this.Animal()
}>
<Text style = {styles.submitButtonText}> Submit </Text>
</TouchableOpacity>
</View>
</View>
);
const SecondRoute = () => (
<View style={[styles.scene, { backgroundColor: '#FFFFFF' }]} >
<Text> {'Name' }</Text>
</View>
);
const ThirdRoute = () => (
<View style={[styles.scene, { backgroundColor: '#FFFFFF' }]} >
<Text> {"Favorite Animal "}</Text>
</View>
);
const initialLayout = { width: Dimensions.get('window').width };
export default function TabViewExample() {
const [index, setIndex] = React.useState(0);
const [routes] = React.useState([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
{ key: 'third', title: 'Third' },
]);
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
third:ThirdRoute
});
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={initialLayout}
/>
);
}
const styles = StyleSheet.create({
scene: {
flex: 1,
},
container: {
paddingTop: 23
},
input: {
margin: 15,
height: 40,
borderColor: '#7a42f4',
borderWidth: 1
},
submitButton: {
backgroundColor: '#65D370',
padding: 10,
margin: 15,
height: 40,
},
submitButtonText:{
color: 'white',
alignSelf:'center',
justifyContent:'center',
borderRadius:20
}
});
Shortest answer, is try to use a state. Using states and passing the state from parent to child may be your best option. Here is one way you can go about it.
1st in your TabViewExample add a useState() hook to keep the form data and change your renderScene() to a function, do not use SceneMap. Example:
...
const [name, setName] = React.useState(undefined);
const renderScene = ({ route }) => {
switch (route.key) {
case "first":
return <FirstRoute setName={setName} />;
case "second":
return <SecondRoute name={name} />;
case "third":
return <ThirdRoute />;
default:
<FirstRoute setName={setName} />;
}
};
(A) The reason for using renderScene() as function is explained with more detail on the "react-native-tab-view" documentation. In short when you need to pass props to components you should not use SceneMap() which you are using above instead turn renderScene into a function and use switch.
(B) We only passed setName to the first component because that's what we'll be using.
2nd - Make use of the props in your components. So now they'll look more or less like this:
const FirstRoute = props => (
<View style={[styles.scene, { backgroundColor: "#FFFFFF" }]}>
<View style={{}}>
<Text style={{ margin: 15 }}>Name </Text>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
placeholder="Name"
placeholderTextColor="#9a73ef"
autoCapitalize="none"
onChangeText={text => props.setName(text)}
/>
...
And for the SecondRoute :
const SecondRoute = props => (
<View style={[styles.scene, { backgroundColor: "#FFFFFF" }]}>
<Text> {props.name}</Text>
</View>
);
So now when you change the first Input in FirstRoute, the name state will automatically be updated, so when you go/swipe to page 2, you should see whatever you typed on the first TextInput on page 1.
PS: this is just a brief explanation so I just gave you the essential idea behind sharing data across tabs/components. On your code you can create cleaner form handler functions and handler functions for those buttons. I could've done it, but I'll leave that job for you as it was not part of your initial question. Hope this helps and let me know if you need a more detailed/in-depth response.
PS 2: If you use my current example don't click the buttons otherwise you'll get errors because you have no handler function, just type on the input and go to the second page to see the result.

route.params not passing properly in my React.js App

I'm trying to figure out why my app isn't working properly. The basic premise is that that the user can choose the various types of cards they want to review. These are broken down into various types and are chosen via checkboxes. This array of settings is then passed to another screen where I take my data from firebase and convert it into an array. These arrays are then compared against one another and if the correct criteria is met, they are added to a new deck. This new deck is then rendered and moved through using a previous and next button. Any help would be appreciated.
My current error is saying length is undefined because when building the deck I need to go through the initial deck of cards (the firebase array).
Current error:
×
TypeError: Cannot read property 'length' of undefined
buildDeck
C:/Users/Langley/Desktop/ArticCards/screens/CardScreen.js:39
36 | let deck = new Array();
37 |
38 | for(var i = 0; i < passDeck.length; i++){
> 39 | for(var j = 0; j < currentSettings.length; j++){
| ^ 40 | if((passDeck.cType[i] == currentSettings[j].arType) && (currentSettings[j].addCV == true)){
41 | deck.push(passDeck[i]);
42 | }
HomeScreen
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, Keyboard, TouchableOpacity, View, TouchableWithoutFeedback, Image } from "react-native";
import { Button } from "react-native-elements";
import { Feather } from "#expo/vector-icons";
import { initArticDB, setupArticListener } from '../helpers/fb-settings';
const HomeScreen = ({route, navigation}) => {
const [ deck, setDeck] = useState([]);
useEffect(() => {
try {
initArticDB();
} catch (err) {
console.log(err);
}
setupArticListener((items) => {
setDeck(items);
});
}, []);
useEffect(() => {
if(route.params?.articCard){
setCard({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
}
if(route.params?.deck){
setDeck({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
}
if(route.params?.articType){
setArticType({arType: state.arType, addCV: state.addCV})
}
}, [route.params?.articType, route.params?.deckeck, route.params?.articCard] );
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate('Settings')
}
>
<Feather
style={styles.headerButton}
name="settings"
size={24}
color="#fff"
/>
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate('About')
}
>
<Text style={styles.headerButton}> About </Text>
</TouchableOpacity>
),
});
return(
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<Text style={styles.textmenu}>Welcome to Artic Cards</Text>
<Text style={styles.textsubmenu}>Press Start to Begin!</Text>
<Image source={require('../assets/5-snowflake-png-image.png')}
style={{width: 300, height: 300, alignSelf: 'center'}}/>
<Button
title="Start"
style={styles.buttons}
onPress={() => navigation.navigate('Cards',
{passDeck: deck})}
/>
<Button
title="Progress"
style={styles.buttons}
onPress={() => navigation.navigate('Progress')}
/>
<Button
title="Customize"
style={styles.buttons}
onPress={() => navigation.navigate('Customize')}
/>
</View>
</TouchableWithoutFeedback>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
backgroundColor: '#E8EAF6',
flex: 1,
justifyContent: 'center'
},
textmenu: {
textAlign: 'center',
fontSize: 30
},
textsubmenu:{
textAlign: 'center',
fontSize: 15
},
headerButton: {
color: '#fff',
fontWeight: 'bold',
margin: 10,
},
buttons: {
padding: 10,
},
inputError: {
color: 'red',
},
input: {
padding: 10,
},
resultsGrid: {
borderColor: '#000',
borderWidth: 1,
},
resultsRow: {
flexDirection: 'row',
borderColor: '#000',
borderBottomWidth: 1,
},
resultsLabelContainer: {
borderRightWidth: 1,
borderRightColor: '#000',
flex: 1,
},
resultsLabelText: {
fontWeight: 'bold',
fontSize: 20,
padding: 10,
},
resultsValueText: {
fontWeight: 'bold',
fontSize: 20,
flex: 1,
padding: 10,
},
});
export default HomeScreen;
SettingScreen
import React, {useState, useEffect} from 'react';
import {StyleSheet, TouchableOpacity, View} from "react-native";
import {Text, CheckBox} from "react-native-elements";
import {FlatList } from "react-native-gesture-handler";
//this is broken some how can't figure out why.
const SettingsScreen = ({route, navigation}) =>{
//create a screen with checkbox fields. One for the consonant-vowel field and the other for the alphabet.
//Both of which will be using flatlists preferably side by side
//A card will only be counted if it meets both values being marked true (category and alpha)
const [articType, setArticType] = useState([
{arType: 'CV', addCV: true},
{arType: 'VC', addCV: true},
{arType: 'VV', addCV: true},
{arType: 'VCV', addCV: true},
{arType: 'CVCV', addCV: true},
{arType: 'C1V1C1V2', addCV: true},
{arType: 'C1V1C2V2', addCV: true},
]);
navigation.setOptions({
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<Text style={styles.headerButton}> Cancel </Text>
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity
onPress={() => {
// navigate back with new settings.
navigation.navigate('Home', {
currentSetting: articType
});
}}
>
<Text style={styles.headerButton}> Save </Text>
</TouchableOpacity>
),
});
const renderCVType = ({index, item}) =>{
return(
<CheckBox
title={item.arType}
checked={item.addCV}
onPress={() => {
let newArr = [... articType];
newArr[index] = {...item, addCV: !item.addCV};
setArticType(newArr);
console.log(newArr);
}}
/>
)
}
return(
<View style={styles.container}>
<Text style={styles.textmenu}>Artic Type</Text>
<Text style={styles.textsubmenu}>Select what words to include based on their cononants and vowels</Text>
<FlatList
keyExtractor={(item) => item.arType}
data={articType}
renderItem={renderCVType}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 10,
backgroundColor: '#E8EAF6',
flex: 1,
},
textmenu: {
textAlign: 'center',
fontSize: 30
},
textsubmenu:{
textAlign: 'center',
fontSize: 15
},
});
export default SettingsScreen;
CardScreen
import React, { useState, useRef, useEffect } from "react";
import { StyleSheet, Text, View } from "react-native";
import { Button, Card } from "react-native-elements";
import { updateArtic } from "../helpers/fb-settings";
import { State } from "react-native-gesture-handler";
//Cannot navigate to this page, not sure why
//general formatting and importing of the deck. Probably put shuffle function here with imported array
//Next and previous buttons should bascially refresh page and give next or previous card
//mastery probably will require setupArticListener (this needs clarification though)
//Deck will be imported here and the information from SettingScreen will be imported here as well
const CardScreen = ({route, navigation}) =>{
const { currentSettings, passDeck } = route.params;
const renderCard = ({index, item}) => {
<View>
<Card
title={item.word}
image={{uri: item.imageUrl}}>
<Text> {item.cType} </Text>
</Card>
</View>
}
const renderMastery = ({index, item}) =>{
return(
<CheckBox
title={'Mastered?'}
checked={!item.mastery}
onPress={() => {
updateArtic({ ...item, mastery: !item.mastery });
}}
/>
)
}
function buildDeck(){
let deck = new Array();
for(var i = 0; i < passDeck.length; i++){
for(var j = 0; j < currentSettings.length; j++){
if((passDeck.cType[i] == currentSettings[j].arType) && (currentSettings[j].addCV == true)){
deck.push(passDeck[i]);
}
}
}
return deck;
}
function nextCard(){
var k = deck.indexOf();
if( (k+1) <= deck.length){
return deck[k+1];
} else{
return deck[0];
}
}
function previousCard(){
var k = deck.indexOf();
if( (k-1) >= 0){
return deck[k-1];
} else{
return deck[(deck.length - 1)];
}
}
buildDeck();
return(
<View>
<Text>Cards</Text>
{renderCard(deck)}
<View style={styles.row}>
<Button
title='Next'
onPress={
nextCard()
}
/>
renderItem{renderMastery}
<Button
title='Previous'
onPress = {
previousCard()
}
/>
</View>
</View>
)
}
const styles= StyleSheet.create({
row: {
flexDirection: 'row',
flex: 1,
marginBottom: 1
},
})
export default CardScreen;

Categories

Resources