首页 > 解决方案 > 在 React Native 中保存数据并发送到另一个类

问题描述

我正在开发的应用程序有一点问题。我必须制作类似笔记应用程序的东西。在那里我有一个按钮可以将我导航到另一个屏幕,我可以在其中写笔记,我有一个保存按钮,应该将我发送回预览屏幕并scrollview更新

这是我迄今为止尝试过的:

应用程序.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;

主.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这样即使在应用程序关闭后我也可以显示它。

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立即显示出来。我必须重新打开应用程序才能显示它。

标签: react-native

解决方案


这里有几件事是错误的:

首先,您仅在 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)}
        />
    );
} 

推荐阅读