2 Câu hỏi: UI không cập nhật cho đến khi chạm vào màn hình khi setState được gọi bên trong một cuộc gọi lại người nghe

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

CẬP NHẬT

MÔ TẢ

Tôi có người nghe trên Realm Object để nhận cập nhật. Khi có bản cập nhật trên máy chủ (hoặc trong máy khách), chức năng được cung cấp cho người nghe gọi setState ({}).

Phần lạ là ngay cả khi bảng điều khiển nói rằng mọi thứ đều ổn và cho thấy phương thức kết xuất được gọi với dữ liệu chính xác, tôi không thể thấy bất kỳ cập nhật nào cho ứng dụng của mình.

Nếu tôi chạm ngẫu nhiên trên màn hình (sau 1 giây, 2 giây, 20 giây), giao diện người dùng cập nhật một cách kỳ diệu và mọi thứ đều chính xác.

Nếu tôi thực hiện cùng một setState với một chức năng được gọi từ một nút mà nó hoạt động, tôi đoán vì hình động của nút kích hoạt cập nhật giao diện người dùng.

Cảm ơn bạn đã đọc cái này.

BƯỚC ĐỂ ĐẠI DIỆN

Bạn phải cập nhật server_url và thông tin xác thực để hoạt động.

thử nghiệm khởi tạo gốc phản ứng npm cài đặt vương quốc cõi liên kết phản ứng gốc

Vì vương quốc chưa sẵn sàng cho 64 bit, bạn cũng phải chắc chắn chỉ biên dịch trong 32 bit để tránh sự cố ứng dụng khi khởi chạy

sử dụng mã này:

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

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

Gói.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"
  }
}

Một số điều kỳ lạ khác:

  • Nếu tôi gỡ lỗi từ xa js để phản ứng trình gỡ lỗi gốc (trên Windows, nhưng tôi đoán là như vậy) thì vấn đề sẽ biến mất.
  • Điều tương tự xảy ra trên 3 thiết bị khác nhau (2 trình giả lập thực, 1 trình giả lập)
2
  1. Nó không sử dụng Expo
    2019-05-11 10: 35: 42Z
  2. Sau đó, có thể bạn có thể cung cấp liên kết github hoặc một cái gì đó khác.
    2019-05-11 10: 36: 14Z
  3. Tôi đã cập nhật ví dụ
    2019-05-11 16: 30: 57Z
2 Câu trả lời                              2                         

Tôi sẽ đề nghị bạn thay đổi khóa của phần tử; điều này sẽ buộc nó tải lại bất cứ điều gì xảy ra.

Ví dụ:

{
  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}
      />
    )
  })
}
    
1
2019-05-11 14: 47: 38Z
  1. Tôi đã thử, nó giống nhau.
    2019-05-11 15: 18: 13Z
  2. @ DxW bạn có thể thêm một cuộc gọi lại cho setState và đảm bảo rằng nó bị bắn khi bài viết được thêm vào không? this.setState ({...}, () = > alert (1)) chẳng hạn; ngoài ra, bạn phải xóa ForceUpdate vì trạng thái đang thay đổi: -)
    2019-05-11 15: 21: 20Z
  3. Tôi đã thử, nó giống nhau. Tôi cũng đã thử sử dụng key = {Date (). GetTime ()} để chắc chắn buộc phải kết xuất lại ở mỗi chu kỳ nhưng không có gì. Điều kỳ lạ là nếu bạn chạm vào màn hình thì mọi thứ đều được cập nhật tốt. Nhưng trong bảng điều khiển, không có gì xảy ra và chu kỳ kết xuất cuối cùng (với dữ liệu chính xác) đã xảy ra khi nhận được thông báo từ người nghe.
    2019-05-11 15: 24: 50Z
  4. có, cuộc gọi lại kích hoạt. Vì có tương tác sau khi tôi đóng cảnh báo, ui được cập nhật. Nhưng tôi đoán chỉ vì sự tương tác. Tôi đang tải lên một ví dụ. Nếu tôi sử dụng nút để thay đổi trạng thái thì nó hoạt động tốt, "đáng ngạc nhiên" ngay cả với TouchableWithoutFeedback (để tránh các hình ảnh động có thể kích hoạt kết xuất lại).
    2019-05-11 15: 45: 19Z
  5. tôi đã cập nhật ví dụ trong câu hỏi của mình
    2019-05-11 15: 56: 35Z
  

CẬP NHẬT 2

     

setState ({}) không hoạt động khi ở trong cuộc gọi lại người nghe. tôi có   vừa thực hiện một thử nghiệm thay đổi mã trong thành phầnDidMount của Home.js,   và theo cách này, nó hoạt động.

Nó không hoạt động vì bạn không ràng buộc phương thức đang gọi nó. nó nằm ngoài bối cảnh thành phần nên setState không có ở đó.

Làm

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

thay vì chức năng thông thường vì chức năng này sẽ liên kết chức năng với ngữ cảnh. ví dụ. bạn cũng có thể liên kết nó trong hàm tạo (nhưng từ những gì tôi đã thấy bạn đã làm một cái gì đó tương tự cho chức năng khác - vì vậy tốt hơn là giữ cho nó nhất quán)

    
1
2019-05-12 09: 19: 41Z
  1. Tôi đã thử nhưng làm điều này không giải quyết được vấn đề :( setState được gọi trong cuộc gọi lại người nghe và tôi có thể thấy dữ liệu thay đổi và phương thức kết xuất bắn trong nhật ký bảng điều khiển Vấn đề duy nhất là luồng UI (có thể?) Không hiển thị các thay đổi cho đến khi tôi nhấn
    2019-05-12 14: 30: 35Z
nguồn đặt đây