Issue
I'm having a hard time trying to pass the value of the TextInput and DropDown Lists from a Child Component to a Parent Component, but in turn the DropDown Lists are sitting as Child Components in the Modal where the TextInput is located.
I tried to implement solutions that I found in online documentations with similar approaches, but I didn't get any progress in my purpose. I'm a newbie to React native programming.
On the other hand, I'm expecting onPress SAVE (<TouchableOpacity>SAVE</TouchableOpacity>) to pass the TextInput and DropDown Lists value from the Child Component to the Form (<Text>{value}</Text>, <Text>{name}</Text>, <Text>{...}</Text> and <Text>{...}</Text>) sitting in the Parent Component.
Thank you in advance for any help you can provide in getting this issue solved.
Here you have my HomeTeamInfo.tsx code which is the Parent Component:
import React, {useState} from 'react';
import {
ActivityIndicator,
Alert,
GestureResponderEvent,
Image,
ImageBackground,
Keyboard,
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
useColorScheme,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import TeamLogo from '../assets/Icons/TeamLogo1.png';
import {Formik} from 'formik';
import * as yup from 'yup';
import FlatButton from './Button';
import {colors} from './colors';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import {RootStackParamList} from '../StackFirst/ScreenMode';
import Icon from 'react-native-vector-icons/Ionicons';
import AddPlayer from '../PlayersPick/AddPlayer';
const titleSchema = yup.object().shape({
title: yup
.string()
.required('Team Name is required')
.matches(
/[A-Za-z]+/,
'Type the right Format (at least one letter is a must)',
)
.min(2, 'Should be a minimum of 2 characters')
.max(14, 'Should be a maximum of 18 characters'),
});
type propsType = NativeStackScreenProps<RootStackParamList, 'HomeTeamInfo'>;
const HomeTeamInfo = (props: propsType) => {
const {route} = props;
const {value} = route.params;
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [visible, setIsVisible] = useState<boolean>(false);
const [image, setImage] = useState<string>('https://ibb.co/rmdD6zz');
const [focused, setFocused] = useState<boolean>(false);
const [name, setName] = useState<string>('');
const [genName, setGenName] = useState([]);
const handleAddName = () => {
setName(name);
console.log(name);
};
const handlePlayerModal = () => {
setIsVisible(false);
};
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.keyboardContainer}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View
style={{
flex: 1,
paddingHorizontal: 10,
backgroundColor: backgroundStyle.backgroundColor,
}}>
<Formik
initialValues={{title: ''}}
validationSchema={titleSchema}
onSubmit={(values, actions) => {
Alert.alert(JSON.stringify(values));
setTimeout(() => {
actions.setSubmitting(false);
}, 1000);
}}>
{({
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
errors,
touched,
isValid,
}) => (
<View style={styles.textContainer}>
<View style={styles.teamComplete}>
<View>
<Image
source={require('../assets/Icons/TeamName.png')}
resizeMode="contain"
style={{
width: 45,
height: 45,
tintColor: isDarkMode ? Colors.lighter : Colors.darker,
}}
/>
</View>
<View style={styles.teamView}>
<TextInput
style={[
{
margin: 3,
borderBottomColor: isValid ? '#088F8F' : '#ff0000',
borderBottomWidth: 1,
fontSize: 20,
padding: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
},
!focused && {
borderBottomWidth: 1,
borderBottomColor: colors.secondary,
shadowOffset: {width: 4, height: 2},
shadowColor: colors.primary,
shadowOpacity: 0.3,
shadowRadius: 2,
},
]}
placeholder="Team Name"
placeholderTextColor={'gray'}
maxLength={14}
inputMode="text"
onChangeText={handleChange('title')}
value={values.title}
autoFocus={false}
onBlur={handleBlur('title')}
onFocus={() => {
setFocused(true);
}}
/>
</View>
</View>
<View style={styles.iconView}>
{values.title.length < 1 ? null : errors.title ? (
<Image
style={{height: 20, width: 20}}
source={require('../assets/Icons/wrong.png')}
/>
) : (
<Image
style={{height: 20, width: 20}}
source={require('../assets/Icons/correct.png')}
/>
)}
<Text style={styles.formikText}>
{touched.title && errors.title}
</Text>
</View>
<View style={{marginTop: 5}}>
<Text
style={{
alignSelf: 'center',
fontSize: 22,
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Team Roster
</Text>
</View>
<View style={styles.players}>
<View
style={{
justifyContent: 'center',
width: '16%',
alignItems: 'center',
}}>
<Text
style={{
color: isDarkMode ? Colors.lighter : Colors.darker,
fontSize: 20,
top: 40,
marginTop: -24,
}}>
{value}
</Text>
<Image
style={{
tintColor: isDarkMode ? Colors.lighter : Colors.darker,
width: 50,
height: 50,
}}
source={require('../assets/Icons/Jersey.png')}
/>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Name
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
fontSize: 20,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
{name}
</Text>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Position
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
...
</Text>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Lineup
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
...
</Text>
</View>
<TouchableOpacity
style={{left: -20, top: -23}}
onPress={() => setIsVisible(true)}>
<Icon
name="add-circle-outline"
size={25}
color={isDarkMode ? Colors.lighter : Colors.darker}
/>
</TouchableOpacity>
{
<AddPlayer
visible={visible}
onClose={handlePlayerModal}
name={name}
handleAddName={handleAddName}
/>
}
</View>
{isSubmitting ? (
<ActivityIndicator
animating={true}
size="large"
color="purple"
/>
) : (
<FlatButton
text="submit"
onPress={
handleSubmit as unknown as (
e: GestureResponderEvent,
) => void
}
/>
)}
</View>
)}
</Formik>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
textContainer: {
flex: 1,
marginTop: 15,
paddingHorizontal: 10,
},
teamComplete: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 10,
},
teamView: {
width: '70%',
},
iconView: {
flexDirection: 'row',
marginLeft: 2,
marginTop: 3,
},
formikText: {
color: '#ff0000',
fontWeight: 'bold',
marginLeft: 10,
},
keyboardContainer: {
flex: 1,
},
players: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: 'purple',
marginTop: 8,
borderRadius: 8,
},
playerImage: {
width: 50,
height: 50,
},
});
export default HomeTeamInfo;
Here is my AddPlayer.tsx code which is a Child Component in HomeTeamInfo.tsx, and in turn has the other three Child Components (AwayTeamInfo.tsx, Position.tsx and LineUp.tsx) from which I also expect to get the value from...
import React, {FC, memo, useEffect, useState} from 'react';
import {
Alert,
Image,
Keyboard,
KeyboardAvoidingView,
Modal,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
useColorScheme,
} from 'react-native';
import Icon1 from 'react-native-vector-icons/AntDesign';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import AwayTeamInfo from '../TeamInfoRec/AwayTeamInfo';
import Position from '../TeamInfoRec/Position';
import LineUp from '../TeamInfoRec/LineUp';
import {colors} from '../TeamInfoRec/colors';
export type AddPlayerProps = {
onClose: () => void;
visible: boolean;
name: string;
handleAddName: () => void;
};
const AddPlayer: FC<AddPlayerProps> = ({
onClose,
visible,
handleAddName}) => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [focused, setFocused] = useState<boolean>(false);
const [name, setName] = useState<string>('');
const [errors, setErrors] = useState<string>('');
return (
<Modal
visible={visible}
onRequestClose={onClose}
transparent
animationType="slide">
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{flex: 1}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.addContainer}>
<View
style={{
backgroundColor: backgroundStyle.backgroundColor,
padding: 18,
top: 2,
width: '90%',
height: 400,
borderRadius: 20,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
}}>
<View style={{alignItems: 'flex-end'}}>
<TouchableOpacity
style={{alignItems: 'center', justifyContent: 'center'}}
onPress={onClose}>
<Icon1
name="close"
size={25}
color={isDarkMode ? Colors.lighter : Colors.darker}
/>
</TouchableOpacity>
</View>
<View style={styles.modalContent}>
<View style={{alignItems: 'center'}}>
<Text
style={{
fontSize: 22,
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Player's Info
</Text>
</View>
<View style={styles.firstTextInput}>
<View style={{width: '25%', left: -26, zIndex: 3}}>
<AwayTeamInfo />
</View>
<View style={{width: '60%', paddingRight: -29}}>
<TextInput
style={{
fontSize: 20,
borderBottomColor: focused
? colors.primary
: colors.secondary,
borderBottomWidth: 2,
left: -5,
paddingRight: -33,
}}
autoCapitalize="words"
placeholder="Name"
maxLength={16}
placeholderTextColor={'gray'}
value={name}
onFocus={() => {
setFocused(true);
}}
onBlur={() => {
setFocused(false);
}}
onChangeText={name => setName(name)}
/>
</View>
<View>
{name !== '' && (
<TouchableOpacity
style={{left: 25}}
onPress={() => setName('')}>
<Image
style={{
height: 25,
width: 25,
top: 2,
left: -13,
tintColor: isDarkMode
? Colors.lighter
: Colors.darker,
}}
source={require('../assets/Icons/clear.png')}
/>
</TouchableOpacity>
)}
</View>
</View>
<View>
<View
style={{
width: '32%',
left: -111,
marginTop: 35,
zIndex: 2,
}}>
<Position />
</View>
</View>
<View>
<View
style={{width: '45%', left: -91, marginTop: 87, zIndex: 1}}>
<LineUp />
</View>
</View>
<TouchableOpacity
disabled={name === ''}
onPress={handleAddName}
style={{
borderRadius: 8,
paddingVertical: 10,
paddingHorizontal: 60,
backgroundColor: 'blue',
top: 88,
left: 74,
}}>
<View>
<Text
style={{
color: 'white',
fontWeight: 'bold',
fontSize: 16,
textAlign: 'center',
}}>
SAVE
</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</Modal>
);
};
const styles = StyleSheet.create({
addContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0.5)',
},
modalContent: {
alignItems: 'center',
alignContent: 'space-between',
flexDirection: 'column',
},
firstTextInput: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: 10,
},
});
export default memo(AddPlayer);
You can have a look to the image descriptions in the following links... https://i.stack.imgur.com/jovS1.jpg https://i.stack.imgur.com/y64bB.jpg
Solution
Since AddPlayer.tsx is the HomeTeamInfo.tsx Child Component you need to initialize the States in the HomeTeamInfo.tsx Component and pass the Props all the way down to the Child (AddPlayer.tsx) and the GrandChildren (AwayTeamInfo.tsx, Position.tsx, and LineUp.tsx) Components where is needed. In addition, you also need to create and pass a function as a Callback all the way down to all the Components (Child and GrandChildren) that you want to be able to change the State from as shown below...
HomeTeamInfo.tsx (Parent Component):
import React, {useState} from 'react';
import {
ActivityIndicator,
Alert,
GestureResponderEvent,
Image,
Keyboard,
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
useColorScheme,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import TeamLogo from '../assets/Icons/TeamLogo1.png';
import {Formik} from 'formik';
import * as yup from 'yup';
import FlatButton from './Button';
import {colors} from './colors';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import {RootStackParamList} from '../StackFirst/ScreenMode';
import Icon from 'react-native-vector-icons/Ionicons';
import AddPlayer from '../PlayersPick/AddPlayer';
type propsType = NativeStackScreenProps<RootStackParamList, 'HomeTeamInfo'>;
const HomeTeamInfo = (props: propsType) => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [name, setName] = useState<string>('');
const [value, setValue] = useState<string | null>('');
const [valuePosition, setValuePosition] = useState<string | null>('');
const [lineup, setLineup] = useState<string | null>('');
const handleAddName = () => {
if (name.trim().length < 3) {
return Alert.alert(
'WARNING! Name must be at least three characters long.',
);
}
setValue(value);
setName(name);
setValuePosition(valuePosition);
setLineup(lineup);
console.log(value);
console.log(name);
console.log(valuePosition);
console.log(lineup);
handlePlayerModal();
};
const handlePlayerModal = () => {
setIsVisible(false);
};
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.keyboardContainer}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View
style={{
flex: 1,
paddingHorizontal: 10,
backgroundColor: backgroundStyle.backgroundColor,
}}>
<Formik
initialValues={{title: ''}}
validationSchema={titleSchema}
onSubmit={(values, actions) => {
Alert.alert(JSON.stringify(values));
setTimeout(() => {
actions.setSubmitting(false);
}, 1000);
}}>
{({
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
errors,
touched,
isValid,
}) => (
<View style={styles.textContainer}>
<View style={styles.teamComplete}>
<View>
<Image
source={require('../assets/Icons/TeamName.png')}
resizeMode="contain"
style={{
width: 45,
height: 45,
tintColor: isDarkMode ? Colors.lighter : Colors.darker,
}}
/>
</View>
<View style={styles.teamView}>
<TextInput
style={[
{
margin: 3,
borderBottomColor: isValid ? '#088F8F' : '#ff0000',
borderBottomWidth: 1,
fontSize: 20,
padding: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
},
!focused && {
borderBottomWidth: 1,
borderBottomColor: colors.secondary,
shadowOffset: {width: 4, height: 2},
shadowColor: colors.primary,
shadowOpacity: 0.3,
shadowRadius: 2,
},
]}
placeholder="Team Name"
placeholderTextColor={'gray'}
maxLength={14}
inputMode="text"
onChangeText={handleChange('title')}
value={values.title}
autoFocus={false}
onBlur={handleBlur('title')}
onFocus={() => {
setFocused(true);
}}
/>
</View>
</View>
<View style={styles.iconView}>
{values.title.length < 1 ? null : errors.title ? (
<Image
style={{height: 20, width: 20}}
source={require('../assets/Icons/wrong.png')}
/>
) : (
<Image
style={{height: 20, width: 20}}
source={require('../assets/Icons/correct.png')}
/>
)}
<Text style={styles.formikText}>
{touched.title && errors.title}
</Text>
</View>
<View style={{marginTop: 5}}>
<Text
style={{
alignSelf: 'center',
fontSize: 22,
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Team Roster
</Text>
</View>
<View style={styles.players}>
<View
style={{
justifyContent: 'center',
width: '16%',
alignItems: 'center',
}}>
<Text
style={{
color: isDarkMode ? Colors.lighter : Colors.darker,
fontSize: 20,
top: 40,
left: 1,
marginTop: -24,
}}>
{value}
</Text>
<Image
style={{
tintColor: isDarkMode ? Colors.lighter : Colors.darker,
width: 50,
height: 50,
}}
source={require('../assets/Icons/Jersey.png')}
/>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Name
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
{name}
</Text>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Position
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
{valuePosition}
</Text>
</View>
<View
style={{
justifyContent: 'center',
borderLeftColor: isDarkMode
? Colors.lighter
: Colors.darker,
borderLeftWidth: 1,
width: '28%',
}}>
<Text
style={{
marginLeft: 5,
alignSelf: 'center',
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Lineup
</Text>
<Text
style={{
alignSelf: 'center',
marginLeft: 5,
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
{lineup}
</Text>
</View>
<TouchableOpacity
style={{left: -20, top: -23}}
onPress={() => setIsVisible(true)}>
<Icon
name="add-circle-outline"
size={25}
color={isDarkMode ? Colors.lighter : Colors.darker}
/>
</TouchableOpacity>
{
<AddPlayer
visible={visible}
onClose={handlePlayerModal}
handleAddName={handleAddName}
value={value}
setValue={setValue}
name={name}
setName={name => setName(name)}
valuePosition={valuePosition}
setValuePosition={setValuePosition}
lineup={lineup}
setLineup={setLineup}
/>
}
</View>
{isSubmitting ? (
<ActivityIndicator
animating={true}
size="large"
color="purple"
/>
) : (
<FlatButton
text="submit"
onPress={
handleSubmit as unknown as (
e: GestureResponderEvent,
) => void
}
/>
)}
</View>
)}
</Formik>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
};
export default HomeTeamInfo;
AddPlayer.tsx (Child Component):
import React, {FC, memo, useState} from 'react';
import {
GestureResponderEvent,
Image,
Keyboard,
KeyboardAvoidingView,
Modal,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
useColorScheme,
} from 'react-native';
import Icon1 from 'react-native-vector-icons/AntDesign';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import AwayTeamInfo from '../TeamInfoRec/AwayTeamInfo';
import Position from '../TeamInfoRec/Position';
import LineUp from '../TeamInfoRec/LineUp';
import {colors} from '../TeamInfoRec/colors';
import {Button} from '@rneui/themed';
import Icon2 from 'react-native-vector-icons/AntDesign';
export type AddPlayerProps = {
onClose: () => void;
visible: boolean;
handleAddName: () => void;
value: string | null;
setValue: (value: React.SetStateAction<string | null>) => void;
name: string;
setName: (value: React.SetStateAction<string>) => void;
valuePosition: string | null;
setValuePosition: (
valuePosition: React.SetStateAction<string | null>,
) => void;
lineup: string | null;
setLineup: (lineup: React.SetStateAction<string | null>) => void;
};
const AddPlayer: FC<AddPlayerProps> = ({
onClose,
visible,
handleAddName,
value,
setValue,
name,
setName,
valuePosition,
setValuePosition,
lineup,
setLineup,
}) => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [focused, setFocused] = useState<boolean>(false);
return (
<Modal
visible={visible}
onRequestClose={onClose}
transparent
animationType="slide">
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{flex: 1}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.addContainer}>
<View
style={{
backgroundColor: backgroundStyle.backgroundColor,
padding: 18,
top: 2,
width: '90%',
height: 400,
borderRadius: 20,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
}}>
<View style={{alignItems: 'flex-end'}}>
<TouchableOpacity
style={{alignItems: 'center', justifyContent: 'center'}}
onPress={onClose}>
<Icon1
name="close"
size={25}
color={isDarkMode ? Colors.lighter : Colors.darker}
/>
</TouchableOpacity>
</View>
<View style={styles.modalContent}>
<View style={{alignItems: 'center'}}>
<Text
style={{
fontSize: 22,
fontWeight: 'bold',
color: isDarkMode ? Colors.lighter : Colors.darker,
}}>
Player's Info
</Text>
</View>
<View style={styles.firstTextInput}>
<View style={{width: '25%', left: -26, zIndex: 3}}>
<AwayTeamInfo value={value} setValue={setValue} />
</View>
<View style={{width: '60%', paddingRight: -29}}>
<TextInput
style={{
fontSize: 20,
borderBottomColor: focused
? colors.primary
: colors.secondary,
borderBottomWidth: 2,
left: -5,
paddingRight: -33,
}}
autoCapitalize="words"
placeholder="Name"
maxLength={16}
placeholderTextColor={'gray'}
value={name}
onFocus={() => {
setFocused(true);
}}
onBlur={() => {
setFocused(false);
}}
onChangeText={name => setName(name)}
/>
</View>
<View>
{name !== '' && (
<TouchableOpacity
style={{left: 25}}
onPress={() => setName('')}>
<Image
style={{
height: 25,
width: 25,
top: 2,
left: -13,
tintColor: isDarkMode
? Colors.lighter
: Colors.darker,
}}
source={require('../assets/Icons/clear.png')}
/>
</TouchableOpacity>
)}
</View>
</View>
<View>
<View
style={{
width: '32%',
left: -111,
marginTop: 35,
zIndex: 2,
}}>
<Position
valuePosition={valuePosition}
setValuePosition={setValuePosition}
/>
</View>
</View>
<View>
<View
style={{width: '45%', left: -91, marginTop: 87, zIndex: 1}}>
<LineUp lineup={lineup} setLineup={setLineup} />
</View>
</View>
<View
style={{
borderRadius: 8,
paddingVertical: 10,
paddingHorizontal: 20,
top: 70,
left: 74,
}}>
<Button
buttonStyle={{height: 50, width: 160}}
icon={<Icon2 name="save" size={26} color="white" />}
radius={'lg'}
size="lg"
color={'secondary'}
title="SAVE"
titleStyle={{
justifyContent: 'center',
alignItems: 'center',
}}
type="solid"
disabled={
name.trim() === '' ||
name.trim().length < 3 ||
value === '' ||
valuePosition === '' ||
lineup === ''
}
disabledStyle={{borderColor: '#AD1457', borderWidth: 3}}
onPress={
handleAddName as unknown as (
e: GestureResponderEvent,
) => void
}
/>
</View>
</View>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</Modal>
);
};
export default memo(AddPlayer);
AwayTeamInfo.tsx (GrandChild Component):
import React, {FC, memo, useState} from 'react';
import {Image, StyleSheet, View, useColorScheme} from 'react-native';
import DropDownPicker from 'react-native-dropdown-picker';
import {Colors} from 'react-native/Libraries/NewAppScreen';
export type DropProps = {
value: string | null;
setValue: (value: React.SetStateAction<string | null>) => void;
};
const AwayTeamInfo: FC<DropProps> = ({
value,
setValue,
}) => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const [open, setOpen] = useState(false);
const [items, setItems] = useState([
{
label: '',
value: '0',
icon: () => (
<Image
source={require('../assets/Icons/Jerseys/0.png')}
style={styles.iconStyle}
/>
),
},
{
label: '',
value: '1',
icon: () => (
<Image
source={require('../assets/Icons/Jerseys/1.png')}
style={styles.iconStyle}
/>
),
},
]);
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: backgroundStyle.backgroundColor,
}}>
<View
style={{
paddingHorizontal: 2,
}}>
<DropDownPicker
style={{backgroundColor: 'cyan'}}
listItemContainerStyle={{
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}}
iconContainerStyle={{borderRadius: 20, width: 10, marginLeft: -13}}
showTickIcon={false}
arrowIconStyle={{left: 11}}
listMode="MODAL"
open={open}
value={value}
items={items}
setOpen={setOpen}
setValue={setValue}
setItems={setItems}
onChangeValue={value => setValue(value)}
placeholder={'#'}
placeholderStyle={{
color: 'black',
fontSize: 20,
fontWeight: 'bold',
}}
selectedItemLabelStyle={{color: 'green', fontWeight: 'bold'}}
labelStyle={{
fontSize: 24,
color: 'green',
fontWeight: 'bold',
alignItems: 'center',
justifyContent: 'center',
marginLeft: -13,
}}
listParentLabelStyle={{
fontWeight: 'bold',
color: 'red',
fontSize: 25,
}}
listChildLabelStyle={{
color: 'red',
}}
/>
</View>
</View>
);
};
export default memo(AwayTeamInfo);
Then just follow the same procedure as above with the remaining two GrandChildren (Position.tsx and LineUp.tsx), i.e. pass the missing Props (valuePosition, setValuePosition, lineup and setLineup,).
In the following links you can see how the image descriptions look like in relation to what is described above:
https://i.stack.imgur.com/KNkpQ.jpg https://i.stack.imgur.com/VyE1o.jpg
The source that I relied on to find a way out of my impasse was the following link...
https://www.youtube.com/watch?v=4J00e1tkCCM
I hope this is helpful to someone.
Answered By - Elvys Pons
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.