如何在 React Native 中正确进行大型状态更新?



我正在编写一个小型的ReactNative应用程序,允许用户邀请人们参加活动。

该设计包括一个受邀者列表,每个受邀者都附有一个用于邀请/取消邀请所述被邀请者的复选框。列表顶部的另一个复选框,用于同时对所有受邀者执行批量邀请/取消邀请。最后,最终将使用一个按钮来发送邀请。

由于每个元素的状态取决于另一个元素所做的更改,因此每当用户对其中一个元素执行操作时,我通常需要重新呈现整个UI。但是,虽然这工作正常,但它给我带来了很多性能问题,如本视频所示

这是我使用的代码:

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

在您的代码中,在类方法toggelSelectAll() {...}中,您可以使用this.state = ...直接修改状态,这是要避免的。仅使用类constructor() {...}中的this.state = ...来初始化状态,并且应仅使用this.setState({...})在其他任何位置更新状态。

不确定这是否有助于解决性能问题,但请尝试将toggelSelectAll()替换为以下内容:

toggelSelectAll() {
const {invitees} = this.state;
const areAllSelectedAlready = invitees.filter(({isSelected}) => !isSelected).length === 0;
this.setState({
invitees: invitees.map(invitee => ({
...invitee,
isSelected: !areAllSelectedAlready
}))
});
}

祝你好运!而且,如果您希望我重构上面的代码以删除构造函数中的第二个this.state = ...,请告诉我(在编写 React 时应再次避免这种情况)。

我建议:

  • 通过创建多个组件来划分代码,这样您就不会有巨大的render()

  • 使用 Redux 存储被邀请者/全局状态,因此您可以选择在修改时应重新渲染哪些组件

这是学习 React Native 的好方法!

相关内容

  • 没有找到相关文章

最新更新