在领域侦听器回调中调用setState时,直到点击屏幕,UI才会更新 [英] UI doesn't update until tap on the screen when setState is called inside a realm listener callback

查看:66
本文介绍了在领域侦听器回调中调用setState时,直到点击屏幕,UI才会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已更新

说明

我在Realm对象上有一个侦听器,用于获取更新.当服务器(或客户端)上有更新时,提供给侦听器的函数将调用setState({}).

I have a listener on a Realm Object for getting updates. When there is an update on the server (or in the client) the function provided to the listener calls setState({}).

奇怪的是,即使控制台说一切正常,并且表明render方法是用正确的数据调用的,我也看不到我的应用程序任何更新.

The strange part is that even if the console says that everything is ok, and it shows that the render method was called with correct data, I can't see any updates to my app.

如果我随机地(在1s,2s,20s ...之后)点击屏幕,UI会神奇地更新,并且一切正确.

If I tap on the screen randomly (after 1s,2s, 20s...) the UI magically updates and everything is correct.

如果我使用从按钮调用的函数执行相同的setState,那么我猜是因为按钮的动画触发了UI更新.

If I do the same setState with a function called from a button it works, I guess because the animation of the button triggers the UI update.

感谢阅读.

要重制

您必须更新server_url和凭据才能正常工作.

反应性初始测试 npm安装领域 反应本机链接领域

react-native init test npm install realm react-native link realm

由于领域尚未为64位做好准备,因此您还必须确保仅在32位中进行编译,以免应用程序在启动时崩溃

Since realm is not ready for 64-bit you must also be sure t compile only in 32bit in order to avoid app crashing when launched

使用此代码:

App.js

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>
    );
  }
}



Schema.js

Schema.js

export const Utente = {
    name: "Utente",
    primaryKey: "id",
    properties: {
        id: "string",
        nome: 'string?',
        permissions: '__Permission[]'
    }
}

Package.json

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个真实的设备,1个仿真器)

推荐答案

更新2

setState({})不起作用.我有 刚刚做了一个测试,更改了Home.js的componentDidMount中的代码, 这样就可以了.

setState({}) doesn't work when is inside the listener callback. I've just done a test changing the code in componentDidMount of Home.js, and in this way, it works.

它不起作用,因为您没有绑定正在调用它的方法.它超出了组件上下文,因此setState不存在.

It doesnt work because you are not binding the method that is calling it. it is beyond component context so setState is not there.

   openRealmAndLogin = (realm_user) => {...}

而不是常规函数,因为它将把函数绑定到上下文.例如您也可以将其绑定到构造函数中(但是从我所看到的情况来看,您已经在为其他函数做类似的事情-最好使其保持一致)

instead of regular function as this one will bind the function to context. e.g. you can also bind it in constructor (but from what i've seen you are already doing something similar for other function - so better to keep it consistent)

这篇关于在领域侦听器回调中调用setState时,直到点击屏幕,UI才会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆