我正在处理的应用程序有点问题。我必须做一个像笔记应用程序的东西。我有一个按钮,可以将我导航到另一个屏幕,我可以在其中编写注释,我有一个保存按钮,可以将我发送回预览屏幕,并scrollview
更新
以下是我迄今为止所做的尝试:
App.js:
import React, { Component } from 'react';
import Main from './app/components/Main.js';
import NoteBody from './app/components/NoteBody.js';
import {StackNavigator} from 'react-navigation'
const App = StackNavigator({Home: {screen: Main}, WriteNote: {screen: NoteBody}});
export default App;
Main.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
ScrollView,
TouchableOpacity,
AsyncStorage,
} from 'react-native';
import Note from './Note';
import NoteBody from './NoteBody.js';
export default class Main extends Component {
static navigationOptions = {
title: 'Notes',
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
}
componentDidMount(){
this.getSavedNotes(this.state.noteArray);
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return <Note key={key} keyval={key} val={val}
deleteMethod={()=>this.deleteNote(key)}/>
});
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<ScrollView style={styles.scrollViewContainer}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<TouchableOpacity onPress={() =>
navigate('WriteNote' ,{onNavigateBack:
this.handleOnNavigateBack.bind(this)})}
style={styles.addButton}>
<Text style={styles.addButtonText}>+</Text>
<Text style={styles.addButtonAditionalText}>Add note</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
deleteNote(key){
this.state.noteArray.splice(key, 1);
this.setState({noteArray: this.state.noteArray});
AsyncStorage.setItem('arr', JSON.stringify(this.state.noteArray));
// alert(this.state.noteArray);
}
getSavedNotes = async (noteArray) =>{
try{
let data = await AsyncStorage.getItem('arr');
if(JSON.parse(data))
{
this.setState({noteArray: JSON.parse(data)});
}
}catch(error){
alert(error);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: {
flex: 1,
},
addButton: {
position: 'relative',
zIndex: 11,
left: 0,
top: 0,
alignItems: 'flex-start',
justifyContent: 'flex-end',
width: 100,
height: 60,
elevation: 8
},
addButtonText: {
color: '#000',
fontSize: 60,
},
addButtonAditionalText: {
color: '#000',
fontSize: 12,
marginLeft: 40,
position: 'absolute',
bottom: 20,
},
scrollViewContainer: {
flex: 1,
marginBottom: 70,
}
});
Note.js:我们有scrollview
以及导航到NoteBody
屏幕的按钮。
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
} from 'react-native';
export default class Note extends Component {
render() {
return (
<View key={this.props.keyval} style={styles.note}>
<Text style={styles.noteText}>{this.props.val.date}</Text>
<Text style={styles.noteText}>{this.props.val.note}</Text>
<TouchableOpacity onPress={this.props.deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}>Del</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
note: {
position: 'relative',
padding: 20,
paddingRight: 100,
borderBottomWidth:2,
borderBottomColor: '#ededed'
},
noteText: {
paddingLeft: 20,
borderLeftWidth: 10,
borderLeftColor: '#0000FF'
},
noteDelete: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2980b9',
padding: 10,
top: 10,
bottom: 10,
right: 10
},
noteDeleteText: {
color: 'white'
}
});
最后是NoteBody:您可以在这里编写注释的正文,并且您还有一个保存按钮,该按钮还应该将数据保存在AsyncStorage
中,这样即使应用程序关闭后我也可以显示它。 / p>
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
AsyncStorage,
} from 'react-native';
import Note from './Note.js';
export default class NoteBody extends Component {
static navigationOptions = {
title: 'Note',
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
}
componentDidMount(){
this.getSavedNotes(this.state.noteArray);
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return <Note key={key} keyval={key} val={val}
deleteMethod={()=>this.deleteNote(key)}/>
});
return (
<View style={styles.container}>
<View style={styles.noteBody}>
<TextInput
multiline = {true}
numberOfLines = {1000000}
style={styles.textInput}
placeholder='Write your note here'
onChangeText={(noteText)=> this.setState({noteText})}
value={this.state.noteText}
placeholderTextColor='grey'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress={ this.addNote.bind(this) } style={styles.addButton}>
<Text style={styles.addButtonText}>SAVE</Text>
</TouchableOpacity>
</View>
);
}
addNote(){
const { navigate } = this.props.navigation;
if(this.state.noteText){
var d = new Date();
this.state.noteArray.push({
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': this.state.noteText
});
this.setState({ noteArray: this.state.noteArray });
this.setState({noteText:''});
AsyncStorage.setItem('arr', JSON.stringify(this.state.noteArray));
this.props.navigation.state.params.onNavigateBack();
navigate('Home');
// alert(this.state.noteArray);
}
}
getSavedNotes = async (noteArray) =>{
try{
let data = await AsyncStorage.getItem('arr');
if(JSON.parse(data))
{
this.setState({noteArray: JSON.parse(data)});
}
}catch(error){
alert(error);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
noteBody:{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 10,
alignItems: 'center',
borderBottomWidth:1,
borderTopColor: '#000',
marginBottom: 100,
},
textInput: {
alignSelf: 'stretch',
textAlignVertical: 'top',
backgroundColor: '#fff',
color: '#000',
padding: 20,
borderTopWidth:2,
borderTopColor: '#ededed',
},
addButton: {
position: 'absolute',
zIndex: 11,
left: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
width: 300,
backgroundColor: '#00FF00',
height: 60,
elevation: 8
},
addButtonText: {
color: '#fff',
fontSize: 24,
},
});
保存按钮仅保存我写的最后一个音符,它甚至不会立即显示在scrollview
上。我必须重新打开应用程序才能显示它。
答案 0 :(得分:1)
这里有一些错误:
首先,您只需在Main组件的构造函数中获取已保存的注释,该注释仅在实例化时调用。放置此代码的建议位置在componentDidMount()中。另外我不明白你为什么要将noteArray状态传递给你的getSavedNotes()方法。
接下来,这是一个重要的问题:从数组添加和删除注释的方法是变异的(拼接和推送)。由于React使用浅比较来确定何时重新渲染,因此在使用setState()时需要创建一个新对象。因此,对于添加,您可以使用concat(),对于删除,Lodash的omit()函数非常有用。或者,您可以使用扩展运算符。
免责声明:我还没有详细阅读您的所有代码,因此可能还有一些其他问题。
编辑:使用FlatList
// render() method of Main.js
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<ScrollView style={styles.scrollViewContainer}>
<ScrollView style={styles.scrollContainer}>
<FlatList
data={this.state.noteArray}
renderItem={({item, index}) => this.renderItem(item, index)}
keyExtractor={(item, index) => `${index}`}
/>
</ScrollView>
<TouchableOpacity onPress={() =>
navigate('WriteNote')}
style={styles.addButton}>
<Text style={styles.addButtonText}>+</Text>
<Text style={styles.addButtonAditionalText}>Add note</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
renderItem = (item, index) => {
return (
<Note
keyval={index}
val={item}
deleteMethod={()=>this.deleteNote(index)}
/>
);
}
答案 1 :(得分:0)
看起来您可以在Main.js中添加listener以获得&#39; onFocus&#39;事件。我会使用回调来查询AsyncStorage并使用结果设置状态。
答案 2 :(得分:0)
屏幕A. 在屏幕A中执行从屏幕B导航回来时想要发生的事情的方法:
handleOnNavigateBack = (foo) => {
this.setState({ FOO }) }
这是屏幕A中的React Navigation方法导航到屏幕B:
this.props.navigation.navigate('ScreenB', {
onNavigateBack: this.handleOnNavigateBack})
...或者如果你的handleOnNavigateBack函数不是一个箭头函数(绑定它),你需要绑定它:(ht @stanica)
this.props.navigation.navigate('ScreenB', {
onNavigateBack:this.handleOnNavigateBack.bind(this) })
屏幕B. 导航到屏幕B并准备导航回屏幕A ...
调用该函数(从屏幕A传递到屏幕B)来执行屏幕A中的操作:
this.props.navigation.state.params.onNavigateBack(this.state.foo)
然后调用React Navigation方法返回(到屏幕A):
this.props.navigation.goBack()
我还更新了我的问题代码,因此它是假定要执行的版本。