React - 我的组件在承诺后没有更新状态



我只是 React-Native 中的一个丐鸢,我每天都会因为 somo 意外的行为而发疯。当然是我的错,我还在学习。 今天,我正在努力理解我的代码是怎么回事。

我有一个函数,可以调用本地存储上的对象数组。如果我安慰承诺的回应,它会给我一个完美的数组(我认为)。之后,我设置状态并使其正确显示在我的控制台上。但是,令我惊讶的是,我的列表组件没有呈现任何东西(而且它肯定像以前一样工作)。

我将附加我的代码:

/*FUNCTION FILE*/
getAllData: async () => {
var data = [{id:null, address:null, name:null}];
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (err, stores) => {
stores.map((result, i, store) => {
// get at each store's key/value so you can work with it
var key = store[i][0];
var value = store[i][1];
data[i] = {id: i, address: key, name: value}
});
});
});
return data},

//MAIN FILE (DAD COMPONENT)
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import NewTagButton from '../components/NewTagButton';
import TagList from '../components/TagList';
import storage from '../functions/Storage';
import { Object } from 'core-js';
//import { TagPosition } from '../functions/GPSTag'
class TagsScreen extends Component {
constructor(props) {
super(props);

this.state = {message:"",
pairedDevices: [], 

};
}
componentDidMount () {
var self = this;
storage.getAllData() //tem que esperar a promise
.then(function (devices) {
self.setState({message: "Scaneamento finalizado."});
self.setState({pairedDevices: devices});

console.log("devices")
console.log(devices)
console.log("State")
console.log(self.state.pairedDevices)
})
.catch(()=> console.log("Promise rejected"))
}

render() {

return (
<View>
<Text>{this.state.message}</Text>
<TagList  devices = {this.state.pairedDevices} origem = 'MyTag'/>
<NewTagButton/>
</View>
);
}
}
export default TagsScreen;

LIST COMPONENT THAT SHOULD RENDER THE LIST
import React from 'react';
import { View,  StyleSheet } from 'react-native';
import TagItem from '../components/TagItem'
const TagList = props => {
const devicesList = props.devices;
const origem = props.origem;
//aqui a gente vai passar device a device para a page TagItem
const items = devicesList.map((device) => 

<TagItem 
key = {device.address}       
address = {device.address} 
name = {device.name}
origem = {origem}/>
);
return (
<View key = {items} styles = {styles.container}>
{items}
</View>
);
}
const styles = StyleSheet.create({
container : {
alignItems:'center',


}
})
export default TagList;

谢谢。

编辑: 我在组件之间放了一些日志,图像在网址上,因为我没有足够的声誉哈哈

控制台日志

编辑2:

我刚刚创建了一个愚蠢的按钮来设置一个只用字符串的状态。此状态更改后,应用将呈现列表。肯定是承诺问题,有人可以帮助我吗?=]

解决方案

AsyncStoragegetAllKeysmultiGet是返回promise。您需要使用 await 从逻辑中返回应用data数据。

getAllData = async () => {
var data = [{id:null, address:null, name:null}];
await AsyncStorage.getAllKeys(async (err, keys) => { // This is async function. 
await AsyncStorage.multiGet(keys, (err, stores) => { // This is async function also. 
stores.map((result, i, store) => {
// get at each store's key/value so you can work with it
var key = store[i][0];
var value = store[i][1];
data[i] = {id: i, address: key, name: value}
});
});
});
console.log(data); // Check your data. 
return data
}

为什么?

它将在完成 Promise 函数的承诺之前返回数据,而无需担心。 按以下顺序检查过程编号。

getAllData = async () => {
var data = [{id:null, address:null, name:null}]; // 1. 
AsyncStorage.getAllKeys((err, keys) => { // 4. there is no async await decoration
AsyncStorage.multiGet(keys, (err, stores) => { // 3. there is no async await decoration 
stores.map((result, i, store) => {
// get at each store's key/value so you can work with it
var key = store[i][0];
var value = store[i][1];
data[i] = {id: i, address: key, name: value}
});
});
});
return data // 2. 
}

因此,从getAllData函数返回时,数据已null。之后,AsyncStorage的函数将应用于data变量。

我已经浏览了你的代码一段时间,想出了一些东西。从本质上讲,你的代码并不完美,但我没有看到任何会像你正在经历的那样破坏它的东西。问题可能出在您正在寻找的地方之外。要么调用TagsScreen,要么TagItem.您使用控制台日志的编辑不是很清楚从何处调用它们,因为您的示例代码尚未更新。

一些笔记可以帮助您上路。

  • 您可以使用console.log('myMessage', myObject);除非使用JSON.stringify()来控制台日志对象,如果您尝试将对象添加到字符串,则会得到[Object object]
  • 在你的承诺中,你不想给self.setState打电话两次。这将呈现应用两次。您可以在控制台中看到这一点.log。这两者都可以在一个集合状态中;一个对象。
  • 在设置状态后立即调用 console.logs 将使状态看起来像未更新。 setState 是异步的,将在清除事件队列后触发。如果要跟踪状态何时更改,请使用 react 生命周期函数componentDidUpdate(oldProps){}
  • 如果您将代码配对,以便它可以在jsFiddle中运行,那将会很有帮助。这是我所得到的,但它工作得很好。我包括了很多评论,解释了到底发生了什么。

我将采取的调试步骤:

  1. TagList中的 deviceList 上添加一个控制台.log以确保它被调用并且数据在那里。
  2. 确保items是 TagItem jsx 对象的数组。
  3. 验证是否正在将TagListhtml 添加到 DOM。

最新更新