在领域侦听器回调中调用 setState 时,在点击屏幕之前,UI 不会更新

IT技术 android reactjs react-native realm realm-js
2021-04-30 15:32:09

更新

描述

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

奇怪的是,即使控制台说一切正常,并且显示使用正确的数据调用了渲染方法,我也看不到我的应用程序的任何更新。

如果我随机点击屏幕(在 1 秒、2 秒、20 秒之后……),UI 会神奇地更新并且一切正常。

如果我对从按钮调用的函数执行相同的 setState 操作,我猜是因为按钮的动画会触发 UI 更新。

感谢您阅读本文。

复制步骤

您必须更新 server_url 和凭据才能工作。

react-native初始化测试 npm 安装领域react-native链接领域

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

使用此代码:

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



架构.js

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

包.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 个模拟器)
3个回答

就我而言,我只是停止调试器 (CMD+D),然后那种奇怪的行为就消失了。 在此处输入图片说明

更新 2

setState({}) 在侦听器回调中不起作用。我刚刚做了一个测试,更改了 Home.js 的 componentDidMount 中的代码,这样,它就可以工作了。

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

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

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

我建议您更改元素的键;这将迫使它重新加载任何发生的事情。

前任:

{
  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}
      />
    )
  })
}