嗨,我在如何将一个类中的数据传递给另一个React Native组件上苦苦挣扎。我可以在同一屏幕上显示数据,但是我想让用户输入一些文本并将其显示在另一个屏幕上。
1)初始屏幕:用户按按钮导航到文本输入,然后将导航回到该屏幕以查看列表。 注意:如果在此处添加列表,则会出现错误“ 未定义不是对象”。因为我无法弄清楚如何将LISTARRAY变量传递到该屏幕。
export const GoalsScreen = ({ navigation }) => {
return (
<SafeAreaView style={styles.container}>
<Header>
{/* header title */}
<Text style={styles.goalText}> Expand your life</Text>
{/* add goal button goto stack */}
<TouchableOpacity onPress={() => navigation.navigate("AddGoal")} >
<Text style={styles.addBtn}> + </Text>
</TouchableOpacity>
</Header>
{/* Error here, need to get data from other screen */}
<FlatList
data={this.state.listArray}
renderItem={({ item, index }) => {
return (
<View>
<Text style={{ fontSize: 30 }}>{item.fireListGoal} </Text>
<Text style={{ fontSize: 20 }}>{item.fireListCat}</Text>
<Text style={{ fontSize: 15 }}> {item.fireListWhy}</Text>
</View>
);
}}
>
</FlatList>
</SafeAreaView>
);
}
2)列表屏幕:如果我将flatList放在这里,一切正常,但是我需要在Firebase实时数据库中通过此处输入的数据,并将其显示在上面显示的另一个屏幕上。
export class AddGoalList extends React.Component {
// state and defult values
constructor(props) {
super(props)
// set inital values
this.state = {
listArray: [],
goal: '',
category: 'Pick One',
why: '',
}
}
//triggers rerendering, put values in a JSON array
componentDidMount() {
goalsRef.on('value', (childSnapshot) => {
const listArray = [];
childSnapshot.forEach((doc) => {
listArray.push({
key: doc.key,
fireListGoal: doc.toJSON().fireListGoal,
fireListCat: doc.toJSON().fireListCat,
fireListWhy: doc.toJSON().fireListWhy
});
this.setState({
listArray: listArray.sort((a, b) => {
return (
a.fireListGoal < b.fireListGoal,
a.fireListCat < b.fireListCat,
a.fireListWhy < b.fireListWhy
);
}),
});
});
});
}
// when button pressed...
onGoal = ({ }) => {
// if form empty alert user
if (this.state.goal.trim() && this.state.why.trim() === '') {
alert("Please fill form.");
return;
}
if (this.state.category.valueOf() === 'Pick One') {
alert("Fill in all inputs.");
return;
}
// otherwise push data to firebase
goalsRef.push({
fireListGoal: this.state.goal,
fireListCat: this.state.category,
fireListWhy: this.state.why
});
}
render() {
return (
// KeyboardAvoidingView ==> prevent keyboard from overlapping
<KeyboardAvoidingView style={styles.container}>
<SafeAreaView>
<Text>Sparks your life!</Text>
{/* Goal title */}
<Text>What is your goal</Text>
<TextInput
placeholder="Enter your goal"
keyboardType='default'
onChangeText={
(text) => {
this.setState({ goal: text });
}
}
value={this.state.goal}
/>
{/* pick selected cetegory */}
<Text>Pick a Category</Text>
{/* picker component */}
<Picker
selectedValue={this.state.category}
onValueChange={(itemValue) => this.setState({ category: itemValue })}
>
<Picker.Item label="Pick One" value="Pick One" />
<Picker.Item label="Fitness" value="Fitness" />
<Picker.Item label="Health" value="Health" />
<Picker.Item label="Travel" value="Travel" />
<Picker.Item label="Wealth" value="Wealth" />
<Picker.Item label="Creativity" value="Creativity" />
<Picker.Item label="Skills" value="Skills" />
</Picker>
<Text>Why did you pick this goal?</Text>
<TextInput
placeholder="Enter your why"
keyboardType='default'
onChangeText={
(text) => {
this.setState({ why: text });
}
}
value={this.state.why}
/>
{/* nav back to My Goal list */}
<Button title="add goal" onPress={this.onGoal.bind(this)} />
</SafeAreaView>
{/* remove list here and add to other GoalsScreen */}
<FlatList
data={this.state.listArray}
renderItem={({ item, index }) => {
return (
<View>
<Text style={{fontSize: 30}}>{item.fireListGoal} </Text>
<Text style={{fontSize: 20}}>{item.fireListCat}</Text>
<Text style={{fontSize: 15}}> {item.fireListWhy}</Text>
</View>
);
}}
>
</FlatList>
</KeyboardAvoidingView>
);
}
}
我已经尝试过使用State并将数据作为参数传递,但是在能够在类中使用变量导航时出现了错误。还试图将其放在一个单独的函数中,现在以太工作了。我将在下面添加代码,以便您查看。任何建议和/或对任何有用文档的引用将不胜感激。
非常感谢您的帮助,在过去的几天里一直试图解决这一问题,但没有运气。非常感谢!
如果我正确理解流程,则需要以下内容:最初,您具有带有项目列表的第一个屏幕(GoalsScreen)。用户可以从那里打开一个新屏幕,可以在其中添加项目(AddGoalScreen)。因此,当用户返回时,您希望他看到更新的列表。
首先,在以上代码中,GoalsSrceen尚未定义任何状态listArray,因此这就是为什么您会得到未定义的错误的原因。您需要像在AddGoalScreen中一样进行声明。另外,如我所见,AddGoalScreen将不再显示此listArray,因此您只需在GoalsScreen中移动goalsRef.on('value', ...
订阅即可。这样做,每次您通过AddGoalScreen推送到Firebase时,on('value')
订阅都会在GoalsScreen内部触发,并且GoalsScreen将重新呈现,从而保持其状态可用。因此,您已解决了问题