[英]react native - Notify parent component of state update in child component with react hooks?
我目前正在嘗試根據我的子 class 組件中所做的更改來更新我的父功能組件中的反應原生鈎子 state。 我一直在尋找並嘗試各種解決方案,但我還沒有找到一個關於功能和 class 組件的解決方案。 下面是我的代碼,它應該做什么,我得到了什么錯誤,以及我嘗試了什么。
它應該做什么
我卡在第 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'
}
});
我試過的:
const [id, setID] = useState(0);
等等。 然后我調用了return()
內的三個<Text>
中的對象。 我嘗試添加 id={id} 等等(你可以看到 rest 被注釋掉了。起初,這些部分沒有被注釋掉,但我得到了錯誤: Can't find variable: firstTwo
。應用程序存在此錯誤時根本不會加載。addFT, addLF, and addRecAmt
函數(因為我評論了調用它們的部分,因為它不起作用),我覺得這也可能是一個問題。 我將它們添加到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 從這里到哪里。
所以總的來說你是對的,在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
...
}
讓我知道它是否有幫助;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.