Android 用户界面不';当在域侦听器回调中调用setState时,在屏幕上点击之前,不会更新
已更新 说明 我在域对象上有一个侦听器,用于获取更新。当服务器(或客户端)上有更新时,提供给侦听器的函数调用setState({}) 奇怪的是,即使控制台说一切正常,并且显示使用正确数据调用了render方法,我也看不到我的应用程序的任何更新 如果我随机点击屏幕(1秒、2秒、20秒……),UI会神奇地更新,一切都是正确的 如果我对一个从按钮调用的函数执行相同的setState,我猜是因为按钮的动画触发了UI更新 谢谢你阅读这篇文章 复制步骤 您必须更新服务器url和凭据才能工作。 反应本机初始化测试 npm安装域 反应本机链接域 由于realm还没有为64位做好准备,您还必须确保仅以32位编译,以避免启动时应用程序崩溃 使用此代码: App.jsAndroid 用户界面不';当在域侦听器回调中调用setState时,在屏幕上点击之前,不会更新,android,reactjs,react-native,realm,realm-js,Android,Reactjs,React Native,Realm,Realm Js,已更新 说明 我在域对象上有一个侦听器,用于获取更新。当服务器(或客户端)上有更新时,提供给侦听器的函数调用setState({}) 奇怪的是,即使控制台说一切正常,并且显示使用正确数据调用了render方法,我也看不到我的应用程序的任何更新 如果我随机点击屏幕(1秒、2秒、20秒……),UI会神奇地更新,一切都是正确的 如果我对一个从按钮调用的函数执行相同的setState,我猜是因为按钮的动画触发了UI更新 谢谢你阅读这篇文章 复制步骤 您必须更新服务器url和凭据才能工作。 反应本机初始化
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import Realm from 'realm'
import { SERVER_URL } from "./config/realm";
import { Utente } from "./config/schema";
export default class App extends Component {
loginAsync = async () => {
var realm_user = Realm.Sync.User.current
if(!realm_user){
const credentials = Realm.Sync.Credentials.usernamePassword('admin', '******' ,false);
realm_user = await Realm.Sync.User.login(SERVER_URL, credentials);
}
const config = realm_user.createConfiguration({
schema: [
Utente,
Realm.Permissions.Permission,
Realm.Permissions.User,
Realm.Permissions.Role],
schemaVersion: 1,
});
this.realm = new Realm(config);
var connectedUserData = this.realm.objects("Utente").filtered("id = $0", realm_user.identity)
connectedUserData.subscribe()
connectedUserData.addListener((connectedUserData)=>{
if(connectedUserData[0]){
this.setState({
connectedUserData: connectedUserData[0]
})
}
})
}
constructor(props){
super(props)
this.loginAsync()
this.state = {
connectedUserData: {
nome: 'not loaded'
}
}
}
render() {
return (
<View style={styles.container}>
<Text>{ this.state.connectedUserData.nome }</Text>
</View>
);
}
}
Package.json
{
"name": "testBaseRealm",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.6.3",
"react-native": "0.57.7",
"realm": "^2.27.0-rc.3"
},
"devDependencies": {
"@babel/core": "7.4.4",
"@babel/runtime": "7.4.4",
"babel-jest": "24.8.0",
"jest": "24.8.0",
"metro-react-native-babel-preset": "0.54.1",
"react-test-renderer": "16.6.3"
},
"jest": {
"preset": "react-native"
}
}
还有一些奇怪的事情:
- 如果我远程调试js以响应本机调试器(在Windows上,但我猜是相同的),问题就会消失
- 同样的事情发生在3个不同的设备上(2个real,1个emulator)
{
articoli.map(articolo=>{
const isLoved=connectedUserData.loved_articles.filtered(“id=$0”,articolo.id)。长度
const isLiked=connectedUserData.liked_articles.filtered(“id=$0”,articolo.id).长度
常量numCommenti=articolo.commenti.length
返回(
)
})
}
更新2
setState({})在侦听器回调中时不工作。我已经
刚刚做了一个测试,修改了Home.js的componentDidMount中的代码,
就这样,它起作用了
它不起作用,因为您没有绑定调用它的方法。它超出了组件上下文,因此setState不存在
做
而不是常规函数,因为它将函数绑定到上下文。e、 g.您也可以在构造函数中绑定它(但从我所看到的情况来看,您已经在为其他函数执行类似的操作-因此最好保持一致)在我的例子中,我只是停止了调试器(CMD+D),奇怪的行为就消失了。
它不使用Expo,那么也许你可以提供一个github链接或其他东西。我更新了示例。你是否尝试在调用构造函数中的loginAsync()之前移动状态初始化?@johnnypeter我尝试过,但仍然不起作用。@DxW你能为setState添加一个回调,并确保在添加文章时触发它吗?例如,this.setState({…},()=>alert(1));由于状态正在更改,您还必须删除forceUpdate:-)我已经尝试过了,它是一样的。我还尝试使用key={Date().getTime()}确保在每个周期强制重新渲染,但什么也不做。奇怪的是,如果你点击屏幕,一切都会更新得很好。但在console中,什么都没有发生,最后一个呈现周期(使用正确的数据)是在从侦听器接收到通知时发生的。是的,会触发回调。由于在我关闭警报后会发生交互,因此ui会得到更新。但我想这只是因为互动。我上传了一个例子。如果我使用一个按钮来改变状态,它工作得很好,“令人惊讶”,即使是没有反馈的触摸屏(为了避免可能触发重新渲染的动画)。@DxW非常奇怪。。老实说,我没有任何线索:’)我确认这种变通方法是有效的。我认为这与此有关setImmediate在当前JavaScript执行块的末尾执行,就在将批处理响应发送回本机之前。请注意,如果在setImmediate回调中调用setImmediate,它将立即执行,其间不会返回到本机。Promise实现使用setImmediate作为其异步原语。“从我开始尝试,但这样做并不能解决问题:(setState在侦听器回调中调用,我可以在控制台日志中看到数据更改和呈现方法触发。唯一的问题是UI线程(可能?)在我点击之前不会呈现更改
{
"name": "testBaseRealm",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.6.3",
"react-native": "0.57.7",
"realm": "^2.27.0-rc.3"
},
"devDependencies": {
"@babel/core": "7.4.4",
"@babel/runtime": "7.4.4",
"babel-jest": "24.8.0",
"jest": "24.8.0",
"metro-react-native-babel-preset": "0.54.1",
"react-test-renderer": "16.6.3"
},
"jest": {
"preset": "react-native"
}
}
{
articoli.map(articolo => {
const isLoved = connectedUserData.loved_articles.filtered("id = $0", articolo.id ).length
const isLiked = connectedUserData.liked_articles.filtered("id = $0", articolo.id ).length
const numCommenti = articolo.commenti.length
return (
<SchedaArticolo
key={ `ALL_${articolo.id}_${isLoved}_${isLiked}_${numCommenti}` }
articolo={articolo}
isLoved={isLoved}
isLiked={isLiked}
numCommenti={numCommenti}
/>
)
})
}
openRealmAndLogin = (realm_user) => {...}