如何使用 TypeScript 将 Props 从孙子组件传递到子组件,然后再传递到 React Native 中的父组件?

问题描述 投票:0回答:1

我很难尝试将 TextInput 和 DropDown 列表的值从子组件传递到父组件,但反过来 DropDown 列表作为子组件位于 TextInput 所在的模态中。

我尝试使用类似的方法实施我在在线文档中找到的解决方案, 但我的目的没有取得任何进展。我是 React 原生编程的新手。

另一方面,我期望 onPress SAVE (SAVE) 将 TextInput 和 DropDown Lists 值从子组件传递到表单 ({value}, {name}, {... }{...}) 位于父组件中。

预先感谢您为解决此问题提供的任何帮助。

这里有我的 HomeTeamInfo.tsx 代码,它是父组件:

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;

这是我的 AddPlayer.tsx 代码,它是 HomeTeamInfo.tsx 中的子组件,并且依次具有其他三个子组件(AwayTeamInfo.tsx、Position.tsx 和 LineUp.tsx),我也希望从中获取值...

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

您可以在以下链接中查看图像描述... https://i.stack.imgur.com/jovS1.jpg https://i.stack.imgur.com/y64bB.jpg

typescript react-native react-hooks react-props react-state
1个回答
0
投票

由于 AddPlayer.tsx 是 HomeTeamInfo.tsx 子组件,因此您需要初始化 HomeTeamInfo.tsx 组件中的状态,并将 Props 一直向下传递给子组件 (AddPlayer.tsx) 和 GrandChildren (AwayTeamInfo.tsx, Position. tsx 和 LineUp.tsx) 需要的组件。此外,您还需要创建一个函数并将其作为回调一直传递到您希望能够更改状态的所有组件(子组件和孙组件),如下所示...

HomeTeamInfo.tsx(父组件):

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(子组件):

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(孙子组件):

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

然后对剩下的两个 GrandChildren(Position.tsx 和 LineUp.tsx)执行与上面相同的过程,即传递缺少的 Props(valuePosition、setValuePosition、lineup 和 setLineup)。

在以下链接中,您可以看到图像描述与上述内容的关系:

https://i.stack.imgur.com/KNkpQ.jpg https://i.stack.imgur.com/VyE1o.jpg

我寻找摆脱僵局的出路所依赖的来源是以下链接......

https://www.youtube.com/watch?v=4J00e1tkCCM

我希望这对某人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.