更新来自其他组件的道具反应原生
Posted
技术标签:
【中文标题】更新来自其他组件的道具反应原生【英文标题】:Update props from other component in react native 【发布时间】:2019-10-17 04:31:25 【问题描述】:我有一个 Main 类,我向用户显示一个数组,然后详细页面用户可以编辑我使用 react 导航参数传递的每个元素。我想在详细信息类中编辑我的数组并使用异步存储进行保存。
//Main.jsimport React from 'react';
import
StyleSheet ,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
KeyboardAvoidingView,
AsyncStorage
from 'react-native'
import Note from './Note'
import detail from './Details'
import createStackNavigator, createAppContainer from "react-navigation";
export default class Main extends React.Component
static navigationOptions =
title: 'To do list',
headerStyle:
backgroundColor: '#f4511e',
,
;
constructor(props)
super(props);
this.state =
noteArray: [],
noteText: '',
dueDate: ''
;
async saveUserTasks(value)
try
await AsyncStorage.setItem('@MySuperStore:userTask',JSON.stringify(value));
catch (error)
console.log("Error saving data" + error);
getUserTasks = async() =>
try
const value = await AsyncStorage.getItem('@MySuperStore:userTask');
if (value !== null)
this.setState( noteArray: JSON.parse(value));
catch (error)
console.log("Error retrieving data" + error);
render()
this.getUserTasks()
let notes = this.state.noteArray.map((val,key) =>
return <Note key=key keyval=key val=val
deleteMethod= () => this.deleteNote(key)
goToDetailPage= () => this.goToNoteDetail(key)
/>
);
const navigation = this.props;
return(
<KeyboardAvoidingView behavior='padding' style=styles.keyboard>
<View style=styles.container>
<ScrollView style=styles.scrollContainer>
notes
</ScrollView>
<View style=styles.footer>
<TextInput
onChangeText=(noteText) => this.setState(noteText)
style=styles.textInput
placeholder='What is your next Task?'
placeholderTextColor='white'
underlineColorandroid = 'transparent'
>
</TextInput>
</View>
<TouchableOpacity onPress=this.addNote.bind(this) style=styles.addButton>
<Text style=styles.addButtonText> + </Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
addNote()
if (this.state.noteText)
var d = new Date();
this.state.noteArray.push(
'creationDate': d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDay(), 'taskName': this.state.noteText,'dueDate':'YYYY/MM/DD'
);
this.setState(noteArray:this.state.noteArray)
this.setState(noteText: '');
this.saveUserTasks(this.state.noteArray)
deleteNote(key)
this.state.noteArray.splice(key,1);
this.setState(noteArray: this.state.noteArray)
this.saveUserTasks(this.state.noteArray)
goToNoteDetail=(key)=>
this.props.navigation.navigate('DetailsScreen',
selectedTask: this.state.noteArray[key],
);
详细视图我有这个方法,类似于在主类中添加注释:
export default class Details extends React.Component
render()
const navigation = this.props;
const selectedTask = navigation.getParam('selectedTask', 'task');
return(
<View key=this.props.keyval style=styles.container>
<TouchableOpacity onPress=this.saveEdit.bind(this) style=styles.saveButton>
<Text style=styles.saveButtonText> save </Text>
</TouchableOpacity>
</View>
);
saveEdit()
let selectedItem = 'creationDate': selectedTask['creationDate'],
'taskName': selectedTask['taskName'],
'dueDate': this.state.dueData
this.props.navigation.state.params.saveEdit(selectedItem)
如何更改任何组件中的道具?
【问题讨论】:
【参考方案1】:首先,您不应该在 render 方法中调用 this.getUserTasks(),因为该函数的 this.setState 很糟糕,我猜它可能会以无限循环结束,或者至少会影响性能。您可以改为在 componentDidMount 中调用它:
componentDidMount = () =>
this.getUserTasks();
或者在构造函数中已经调用,但我更喜欢第一个选项:
constructor(props)
super(props);
this.state =
noteArray: [],
noteText: '',
dueDate: ''
;
this.getUserTasks()
this.props.noteArray.push(.. 可能是未定义的,因为你没有将它传递到任何地方。(在你的 sn-p 中没有看到任何引用)。我想我会实现 saveEdit 函数在 Main.js 组件中,只需将其传递给导航路由,并通过访问导航状态道具调用 Details 组件中的函数:
更新
goToNoteDetail=(key)=>
this.props.navigation.navigate('DetailsScreen',
// selectedTask: this.state.noteArray[key],
selectedItem: key,
saveEdit: this.saveEdit
);
saveEdit(selectedItem)
const selectedTask = this.state.noteArray[selectedItem]
this.state.noteArray.push(
'creationDate': selectedTask['creationDate'],
'taskName': selectedTask['taskName'],
'dueDate': this.state.dueData
);
this.setState(noteArray:this.state.noteArray)
this.setState(dueData: 'YYYY/MM/DD');
this.saveUserTasks(this.state.noteArray)
然后在Details组件中调用saveEdit:
saveSelectedItem = () =>
const navigation = this.props.navigation;
const selectedItem, saveEdit = navigation.state && navigation.state.params;
saveEdit(selectedItem)
【讨论】:
那我应该如何实现 saveEdit 方法,以便我可以传递 ' 'creationDate': selectedTask['creationDate'], 'taskName': selectedTask['taskName'],'dueDate':this.state .dueData' 这个来自详细组件 @Niloufar 检查我的更新。当您导航到详细信息屏幕时,您将键设置为 selectedItem(如果您愿意,也可以将其设置为“键”)。然后,当您从 Details 组件调用 saveEdit 时,只需将 selectedItem 作为参数传递来识别当前/选定的任务以更新任务。希望这会有所帮助 谢谢,但是这行 const selectedItem, saveEdit = navigation.state && navigation.state.params; 我仍然有错误“未定义不是一个对象(评估'navigation.state') 亲爱的 BigPun 请检查我的更新,这样你就会知道我的代码是否有任何错误,我是反应原生的新手并且很困惑 我试图再次检查您的解决方案,但现在我得到'未定义不是对象(评估'navigation.state')以上是关于更新来自其他组件的道具反应原生的主要内容,如果未能解决你的问题,请参考以下文章
当用户输入通过来自另一个组件的道具的文本时,在反应 js 中不起作用