简体   繁体   English

"我在 React Native 中遇到了关于异步存储的问题"

[英]i am facing a problem regarding async storage in react native

i am facing a problem regarding async storage in react native .我在 react native 中遇到了关于异步存储的问题。

when i setItem in async storage and then retrieve it if there are 3 tasks- which i have added,当我在异步存储中设置项目,然后如果有 3 个任务(我已添加)检索它,

only two of them is retrieved只检索到其中两个

i will share a photo of before and after我将分享之前和之后的照片

this is output before refreshing<\/a>这是刷新前的输出<\/a>

this is the output after refreshing the app<\/a>这是刷新应用程序后的输出<\/a>

This is my app.js code这是我的 app.js 代码

import { StatusBar } from 'expo-status-bar';
import {
  StyleSheet,
  Text,
  View,
  KeyboardAvoidingView,
  FlatList,
  TextInput,
  TouchableOpacity,
  Keyboard,
} from 'react-native';
import React, { Component } from 'react';
import * as Font from 'expo-font';
import Task from './components/Task';
import AppLoading from 'expo-app-loading';
import AsyncStorage from '@react-native-async-storage/async-storage';

let customFonts = {
  Poppins_SemiBold: require('./assets/Poppins-SemiBold.ttf'),
  Poppins_Regular: require('./assets/Poppins-Regular.ttf'),
};

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      task: '',
      taskItems: [],
      fontsLoaded: false,
    };
  }
  async _loadFontsAsync() {
    await Font.loadAsync(customFonts);
    this.setState({ fontsLoaded: true });
  }
  componentDidMount() {
    this._loadFontsAsync();
    this._retrieveData()
  }
  _retrieveData = async () => {
  try {
    const value = await AsyncStorage.getItem('data');
    if (value.length !== 2) {
      // We have data!!
      this.setState({taskItems:[...JSON.parse(value)]})
      console.log(value);
    }
    
   
  } catch (error) {
    // Error retrieving data
    console.log(error)
  }
};
  handleAddTask=()=>{
    Keyboard.dismiss()
    this.setState({taskItems:[...this.state.taskItems,this.state.task]})
    this.setState({task:''})
    AsyncStorage.setItem('data',JSON.stringify(this.state.taskItems))
  }
  deleteItem=(index)=>{
    try {
      let arr = [...this.state.taskItems];
      arr.splice(index, 1);
      this.setState({taskItems:arr})
      AsyncStorage.setItem('data',JSON.stringify(arr))
      
      
    } catch (err) {
      console.log(err);
    }
  }
  render() {
    if (!this.state.fontsLoaded) {
      return <AppLoading />;
    }

    return (
      <View style={styles.container}>
        {/* Todays Tasks */}

        <View style={styles.taskWrapper}>
          <Text style={styles.sectionTitle}>Today's Tasks</Text>
          <View style={styles.items}>
            {/* This is where the tasks will go! */}
            <FlatList
              data={this.state.taskItems}
              keyExtractor={(item) => item}
              renderItem={({ item, index }) => (
                <Task text={item} handleDelete={() => this.deleteItem(index)} />
              )}
            />
          </View>
        </View>

        {/* Write a Task */}
        <KeyboardAvoidingView style={styles.writeTaskWrapper}>
          <TextInput
            style={styles.input}
            placeholder={'Write A Task!'}
            onChangeText={(text) => {
              this.setState({ task: text });
            }}
            value={this.state.task}
          />
          <TouchableOpacity
            onPress={() => {
              this.handleAddTask();
            }}>
            <View style={styles.addWrapper}>
              <Text style={styles.addText}>+</Text>
            </View>
          </TouchableOpacity>
        </KeyboardAvoidingView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#E8EAED',
  },
  taskWrapper: {
    paddingTop: 80,
    paddingHorizontal: 20,
  },
  sectionTitle: {
    fontSize: 24,
    backgroundColor: '#fff',
    fontFamily: 'Poppins_SemiBold',
    borderRadius: 10,
    margin: 'auto',
    width: 250,
    height: 60,
    textAlign: 'center',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.2,
    shadowRadius: 2,
    elevation: 5,
    paddingTop: 10,
  },
  items: {
    marginTop: 30,
  },
  writeTaskWrapper: {
    position: 'absolute',
    bottom: 60,
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  input: {
    paddingVertical: 15,
    paddingHorizontal: 15,
    backgroundColor: '#fff',
    borderRadius: 60,
    width: 250,

    fontFamily: 'Poppins_Regular',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.5,
    shadowRadius: 2,
    elevation: 3,
  },
  addWrapper: {
    width: 60,
    height: 60,
    backgroundColor: '#fff',
    borderRadius: 60,
    justifyContent: 'center',
    alignItems: 'center',

    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.5,
    shadowRadius: 2,
    elevation: 3,
  },
  addText: {},
});

Due to React internal state update implementation, update Async storage run before new state updated.由于 React 内部状态更新实现,更新异步存储在新状态更新之前运行。 It's recommended to run asynchronous code before updating the state.建议在更新状态之前运行异步代码。

To solve the issue, refactor your code as below:为了解决这个问题,重构你的代码如下:


handleAddTask= async ()=>{
   Keyboard.dismiss()
   const updatedTaskItems = [...this.state.taskItems,this.state.task]
   await  AsyncStorage.setItem('data',JSON.stringify(updatedTaskItem))
   this.setState({taskItems:updatedTaskUtems,task:''})
    
  }


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM