реагировать родным - уведомить родительский компонент об обновлении состояния в дочернем компоненте с помощью ловушек реагирования? - PullRequest
1 голос
/ 10 апреля 2020

В настоящее время я пытаюсь обновить собственное состояние ответа в моем родительском функциональном компоненте на основе изменений, внесенных в мой дочерний класс. Я искал и пробовал различные решения, но я не нашел ни одного, который бы касался функциональных и классных компонентов. Ниже приведен мой код, что он должен делать, какие ошибки я получаю и что я пробовал.

Что он должен делать

  1. На Обзорных карточках есть кнопка, позволяющая вам добавить карточку.
  2. AddCard позволяет заполнить некоторые поля TextInput
  3. AddCard должна позволить вам нажать кнопку сохранения и вернуться к экран карты обзора.
  4. Информация, которую пользователь заполнил на шаге 2, должна отображаться на экране карты обзора.

Я застреваю на шаге 4.

Приложение. js

import React, { useState } from 'react';
import { StyleSheet, Text, TextInput, View, Button, TouchableOpacity, ShadowPropTypesIOS } from 'react-native';
import AddCard from './components/AddCard.js';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useNavigation } from '@react-navigation/native';

// function returnData(id, firstTwo, lastFour, recentAmount) {
//   this.setState({id: id, firstTwoDigits: firstTwo, lastFourDigits: lastFour, currentAmt: recentAmount});
// }

function HomeScreen({ navigation }) {
  const [id, setID ] = useState(0);
  // const [firstTwo, setFirstTwoDigits] = useState(0);
  const [lastFour, setLastFourDigits] = useState(0);
  const [recentAmount, setRecentAmount] = useState(0);
  return (
    <View style={styles.homeContainer}>
      <Button title="Add Card" onPress={() => navigation.navigate('Add Card')}/>
      <Text>
      CardID: {id}
      </Text>
      <Text>
      Last Four Digits: {lastFour}
      </Text>
      <Text>
      Current Amount: {recentAmount}
      </Text>
      <Text style={styles.textStyle} >VISA xxxx</Text>
      <Text style={styles.textStyle}>MASTERCARD xxxx</Text>
      <Text style={styles.textStyle}>AMEX xxxx</Text>
    </View>
  );
}

function AddCardScreen({ navigation }) {
  return (
    <View style={styles.addCardContainer}>
      <AddCard 
      navigation={navigation}
      id={id}
      // firstTwo={firstTwo}
      // lastFour={lastFour}
      // recentAmount={recentAmount} 
      />
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Overview Cards' }} />
        <Stack.Screen name="Add Card" component={AddCardScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
// function AddCardButton(){
//       return (
//           <View style={styles.buttonContainer}>
//               <TouchableOpacity>
//                   <Text style={styles.button}>Add Card</Text>
//               </TouchableOpacity>
//           </View>
//       );
//   }

export default App;

const styles = StyleSheet.create({
  homeContainer: {
    flex: 1,
    backgroundColor: '#ef95b1',
    alignItems: 'center',
    justifyContent: 'flex-start',
  },
  addCardContainer: {
    flex: 1,
    backgroundColor: '#28cdf0',
    justifyContent: 'flex-start',
  },
  buttonContainer: {
    flexDirection: 'row',
    alignSelf: 'flex-end',
    marginTop: 15,
  },
  button: {
    flexDirection: 'row',
    alignSelf: 'flex-end',
    marginTop: 15,
    right: 10,
    backgroundColor: '#2565ae',
    borderWidth: 1,
    borderRadius: 12,
    color: 'white',
    fontSize: 15,
    fontWeight: 'bold',
    overflow: 'hidden',
    padding: 10,
    textAlign:'center',
  },
  textStyle: {
    padding: 10,
  }
});

AddCard. js

import React, { Component } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity } from 'react-native';
import { Input } from 'react-native-elements'
import { ScrollView } from 'react-native-gesture-handler';
// import { loadSettings, saveSettings } from '../storage/settingsStorage';

class AddCardScreen extends Component {
   constructor(props) {
    super(props);
    this.state = {
        firstTwo  : '',
        lastFour  : '',
        recentAmt : ''
    };

    this.addFT = this.addFT.bind(this)
    this.addLF = this.addLF.bind(this)
    this.addRecAmt = this.addRecAmt.bind(this)
   }

   static navigationOptions = {
       title: 'Add Card'
    };

   addFT(firstTwo) {
    this.setState(Object.assign({}, this.state.firstTwo, { firstTwo }));
  }

  addLF(lastFour) {
    this.setState(Object.assign({}, this.state.lastFour, { lastFour }));
  }

  addRecAmt(recentAmt) {
    this.setState(Object.assign({}, this.state.recentAmt, { recentAmt }));
  }

   handleSubmit() {
    const { navigation } = this.props;
    alert('New card saved. Returning to Home to view addition.');
    // navigation.state.params.returnData('123', this.firstTwo, this.lastFour, this.recentAmt);
    navigation.navigate('Home', this.firstTwo, this.lastFour, this.recentAmt);
  }

    render() {
        const {navigation} = this.props;
        return (
            <ScrollView>
                <View style={styles.inputContainer}>
                    <TextInput 
                    style={styles.textInput}
                    placeholder="First two digits of card"
                    placeholderTextColor="#000000"
                    keyboardType={'number-pad'}
                    maxLength = {2}

                    // onChangeText={this.addFT}
                    // inputValFT={this.state.firstTwo}
                    />
                    <TextInput
                    style={styles.textInput}
                    placeholder="Last four digits of card"
                    placeholderTextColor="#000000"
                    keyboardType={'number-pad'}
                    maxLength = {4}

                    // onChangeText={this.addLF}
                    // inputValLF={this.state.lastFour}
                    />
                    <TextInput
                    style={styles.textInput}
                    placeholder="Most recent dollar amount"
                    placeholderTextColor="#000000"
                    keyboardType={'decimal-pad'}

                    // onChangeText={this.addRecAmt}
                    // inputValRA={this.state.recentAmt}
                    />
                </View>
                <View style={styles.inputContainer}>
                    <TouchableOpacity 
                    style={styles.saveButton}
                    onPress={this.handleSubmit.bind(this)}>
                        <Text style={styles.saveButtonText}>Save</Text>
                    </TouchableOpacity>
                </View>
            </ScrollView>
        );
    }
}
// () => navigation.navigate('Home') line 81
export default AddCardScreen;

const styles = StyleSheet.create({
    inputContainer: {
        paddingTop: 15
      },
      textInput: {
        borderColor: '#FFFFFF',
        textAlign: 'center',
        borderTopWidth: 1,
        borderBottomWidth: 1,
        height: 50,
        fontSize: 17,
        paddingLeft: 20,
        paddingRight: 20
      },
      saveButton: {
        borderWidth: 1,
        borderColor: '#007BFF',
        backgroundColor: '#007BFF',
        padding: 15,
        margin: 5
      },
      saveButtonText: {
        color: '#FFFFFF',
        fontSize: 20,
        textAlign: 'center'
      }

});

Что я пробовал:

  1. Я пытался добавить React Hook к моему родительскому компоненту HomeScreen. Я добавил const [id, setID] = useState(0); и так далее. Затем я назвал объекты в трех <Text>, которые находятся внутри return(). Я попытался добавить id = {id} и так далее (вы можете видеть, что все остальное закомментировано. Сначала эти части не были закомментированы, но я получаю сообщение об ошибке: Can't find variable: firstTwo. Приложение не загружается вообще, когда эта ошибка существует.
  2. Я заметил, что я не использовал функции addFT, addLF, and addRecAmt в AddCard. js вообще (так как я прокомментировал части, где они вызываются, так как это не было работая), что, как мне показалось, тоже может быть проблемой. Я добавил их в handleSubmit().

Примерно так:

handleSubmit(firstTwo, lastFour, recentAmt) {
    const { navigation } = this.props;
    this.addFT(firstTwo);
    this.addLF(lastFour);
    this.addRecAmt(recentAmt);
    alert('New card saved. Returning to Home to view addition.');
    // navigation.state.params.returnData('123', this.firstTwo, this.lastFour, this.recentAmt);
    navigation.navigate('Home', this.firstTwo, this.lastFour, this.recentAmt);
  }

Мне пришлось комментировать id = {id} потому что, если бы я этого не сделал, это произвело бы ту же ошибку, что и firstTwo, если бы она не была закомментирована. Приложение прекрасно загружается с этим изменением в App. js и AddCard. js. Я хочу сделать, но я не уверен, где go отсюда.

1 Ответ

1 голос
/ 10 апреля 2020

так что вы были правы в целом, в handleSubmit вы должны перейти к вашему Home экрану с параметрами (другие данные шагов)

handleSubmit(firstTwo, lastFour, recentAmt) {
  ...
  navigation.navigate('Home', {
    firstTwo: this.state.firstTwo,
    lastFour: this.state.lastFour,
    recentAmt: this.state.recentAmt,
  });
}

Теперь он Home показывает экран route с параметрами должны быть доступны:

function HomeScreen({ route }) {
  const { firstTwo, lastFour, recentAmt } = route.params || {}; // in case we have no params it is undefined by the default

  const [lastFour, setLastFourDigits] = useState(lastFour || ''); // using it as a default value for our state variable
  ...
}

дайте мне знать, помогло это или нет;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...