Saya sedang menulis aplikasi ReactNative kecil yang memungkinkan pengguna mengundang orang ke acara.

Desainnya mencakup daftar undangan, yang masing-masing disertai dengan kotak centang yang digunakan untuk mengundang/membatalkan undangan tersebut. Kotak centang lain di bagian atas daftar yang melakukan undangan/pembatalan undangan massal pada semua undangan secara bersamaan. Akhirnya sebuah tombol pada akhirnya akan digunakan untuk mengirimkan undangan.

Karena status masing-masing elemen ini bergantung pada perubahan yang dibuat oleh elemen lainnya, saya sering kali perlu merender ulang seluruh UI saya setiap kali pengguna mengambil tindakan pada salah satunya. Tetapi sementara ini berfungsi dengan benar, ini menyebabkan saya beberapa masalah kinerja, sebagai ditampilkan dalam video ini

Berikut kode yang saya gunakan:

import React, { Component } from 'react';
import { Container, Header, Title, 
    Content, Footer, FooterTab, 
    Button, Left, Right, 
    Center, Body, Text, Spinner, Toast, Root , CheckBox, ListItem, Thumbnail} from 'native-base';

import { FlatList, View } from 'react-native';

export default class EventInviteComponent extends Component {


constructor(props) {
    super(props);
    console.disableYellowBox = true; 

    this.state = {
        eventName: "Cool Outing!",
        invitees:[]
    }

    for(i = 0; i < 50; i++){
        this.state.invitees[i] = { 
            name: "Peter the " + i + "th",
            isSelected: false,
            thumbnailUrl: 'https://is1-ssl.mzstatic.com/image/thumb/Purple111/v4/62/08/7e/62087ed8-5016-3ed0-ca33-50d33a5d8497/source/512x512bb.jpg'
        }
      }


    this.toggelSelectAll = this.toggelSelectAll.bind(this)
}

toggelSelectAll(){
    let invitees = [...this.state.invitees].slice();
    let shouldInviteAll = invitees.filter(invitee => !invitee.isSelected).length != 0

    let newState = this.state;
    newState = invitees.map(function(invitee){
        invitee.isSelected = shouldInviteAll;
        return invitee;
        });
    this.setState(newState);
}


render() {

    let invitees = [...this.state.invitees];

    return (
        <Root>
            <Container>

                <Content>
                    <Text>{this.state.eventName}</Text>

                    <View style={{flexDirection: 'row', height: 50, marginLeft:10, marginTop:20}}>
                        <CheckBox 
                    checked={this.state.invitees.filter(invitee => !invitee.isSelected).length == 0}
                    onPress={this.toggelSelectAll}/>
                        <Text style={{marginLeft:30 }}>Select/deselect all</Text>
                    </View>

                    <FlatList
                    keyExtractor={(invitee, index) => invitee.name}
                    data={invitees}
                    renderItem={(item)=> 
                        <ListItem avatar style={{paddingTop: 20}}>
                            <Left>
                              <Thumbnail source={{ uri: item.item.thumbnailUrl}} />
                            </Left>
                            <Body>
                                <Text>{item.item.name}</Text>
                                <Text note> </Text>
                            </Body>
                            <Right>
                                <CheckBox 
                                checked={item.item.isSelected}/>
                            </Right>
                        </ListItem>}/>

                </Content>

                <Footer>
                    <FooterTab>
                        <Button full
                         active={invitees.filter(invitee => invitee.isSelected).length > 0}>
                            <Text>Invite!</Text>
                        </Button>
                    </FooterTab>
                </Footer>

            </Container>
        </Root>);
    }
}
0
Spaci Tron 23 November 2017, 14:14
Saya punya beberapa saran di sini: #1. Anda tidak perlu mengkloning array dalam fungsi render. #2. Negara tidak boleh berisi segala sesuatu seperti yang Anda lakukan. Saya pikir itu bisa berupa susunan id undangan. #3. Aneh bahwa FlatList tidak meningkatkan apa pun di sini. Anda mungkin ingin mendapatkan referensi ke kotak centang dan beralih masing-masing alih-alih merender ulang semuanya. Semoga bisa membantu
 – 
idealweek.net
23 November 2017, 19:11

2 jawaban

Dalam kode Anda, dalam metode kelas toggelSelectAll() {...} Anda mengubah status secara langsung dengan menggunakan this.state = ..., yang merupakan sesuatu yang harus dihindari. Hanya gunakan this.state = ... di kelas Anda constructor() {...} untuk menginisialisasi status, dan Anda hanya boleh menggunakan this.setState({...}) untuk memperbarui status di tempat lain.

Tidak yakin apakah ini akan membantu masalah kinerja Anda, tetapi coba ganti toggelSelectAll() dengan yang berikut ini:

toggelSelectAll() {
  const {invitees} = this.state;

  const areAllSelectedAlready = invitees.filter(({isSelected}) => !isSelected).length === 0;

  this.setState({
    invitees: invitees.map(invitee => ({
      ...invitee,
      isSelected: !areAllSelectedAlready
    }))
  });
}

Semoga beruntung! Dan, beri tahu saya jika Anda ingin saya memperbaiki kode di atas untuk menghapus this.state = ... ke-2 di konstruktor Anda (yang, sekali lagi, harus dihindari saat menulis React).

1
sammysaglam 23 November 2017, 14:46
1
Kamu benar. Ada kesalahan ketik. Saya memperbaikinya sekarang tetapi tidak, itu tidak membantu meningkatkan kinerja.
 – 
Spaci Tron
23 November 2017, 14:51
Ah! dipahami. Meskipun demikian, saya tidak begitu yakin mengapa Anda mengalami masalah kinerja; sangat aneh karena memperbarui hanya 50 catatan seharusnya tidak menyebabkan masalah ini.
 – 
sammysaglam
23 November 2017, 14:53
1
Untuk beberapa alasan animasi kotak centang diblokir oleh utas JS.
 – 
Spaci Tron
23 November 2017, 15:00
Mungkinkah ada masalah dengan prop <CheckBox> checked? mungkin perhitungan menggunakan invitees.filter() lambat?
 – 
sammysaglam
23 November 2017, 15:01
Juga, coba tambahkan pernyataan console.log() di suatu tempat --> mungkin terjadi loop besar & tidak perlu dan metode render() dipanggil 1000+ kali di salah satu komponen?
 – 
sammysaglam
23 November 2017, 15:03

Saya menyarankan:

  • Membagi kode Anda dengan membuat beberapa komponen, sehingga Anda tidak akan memiliki render() yang besar

  • Menggunakan Redux untuk menyimpan undangan / status global, sehingga Anda dapat memilih komponen mana yang harus dirender ulang jika terjadi modifikasi

Itu cara yang bagus untuk belajar React Native!

0
Maxime 23 November 2017, 14:34