gpt4 book ai didi

javascript - setState 也会改变屏幕 Prop

转载 作者:行者123 更新时间:2023-11-30 20:11:12 24 4
gpt4 key购买 nike

我有一个大问题。我有一个从另一个屏幕接收一些 Prop 的屏幕,我通过 <TicketDiaryHour {...this.props} /> 将这些 Prop 传递到那个屏幕的组件中。 .我在方法 componentDidMount() 中将组件中的这些 Prop 设置为我的状态。

在该组件 (TicketDiaryHour) 中,我也有 flatlist。我的问题是我更改了 flatlist 中的数据(通过 setState)并且 props 也在更改......我不知道为什么会这样。

我的 componentDidUpdate() 返回 prevProps == this.props 和 prevState == this.state。我不知道为什么...

看:

Prev props: {"navigation":{"state":{"params":{"props":{"id":"418103","headingText":"Klavir","roomText":"Mala dvorana","student":"Ives Berlovčnik","apsent":"1/1","startTime":"07:00","endTime":"07:30","finished":"0","listOfStudents":[{"nameLastname":"Ives Berlovčnik","id":"43275","checked":false,"o":true,"n":false}],"minutes":"30","notes":"","lesson":""}}}

This props: {"navigation":{"state":{"params":{"props":{"id":"418103","headingText":"Klavir","roomText":"Mala dvorana","student":"Ives Berlovčnik","apsent":"1/1","startTime":"07:00","endTime":"07:30","finished":"0","listOfStudents":[{"nameLastname":"Ives Berlovčnik","id":"43275","checked":false,"o":true,"n":false}],"minutes":"30","notes":"","lesson":""}}}

组件代码:平面列表;

<FlatList
ref={(list) => this.myList = list}
style={[styles.flatList,{height: this.state.height}]}
data={this.state.data}
scrollEnabled = {this.state.showList ? true : false}

contentContainerStyle={{ padding: 15 }}
renderItem={({ item }) => (

<View style={styles.listItemStyle}>
<View style={{flexDirection: 'row', marginBottom: 7, }}>

{
item.checked &&
<TouchableOpacity
onPress={this.changeCheckedToFalse.bind(this,item)}>
<View style={styles.checked} />
</TouchableOpacity> ||
<TouchableOpacity
onPress={this.changeCheckedToTrue.bind(this,item)}>
<View style={styles.unchecked} />
</TouchableOpacity>
}


<Text style={{color: '#000', opacity: 0.6}}>{item.nameLastname}</Text>
{
item.checked &&
<View style={{position: 'absolute', right: 0 }}>
<View style={{flexDirection: 'row'}} >
{
item.o &&
<TouchableOpacity
style={[styles.touchable1Ch,styles.iconStyle1]}
onPress={this.changeSelectionO.bind(this,item)}>

<Text style={{color: '#fff', fontSize: 18, alignSelf: 'center' }}>O</Text>
</TouchableOpacity> ||
<TouchableOpacity
style={[styles.touchable1,styles.iconStyle1]}
onPress={this.changeSelectionO.bind(this,item)}>

<Text style={{color: '#fff', fontSize: 15, alignSelf: 'center' }}>O</Text>
</TouchableOpacity>
}
{
item.n &&
<TouchableOpacity
style={[styles.touchable2Ch,styles.iconStyle1]}
onPress={this.changeSelectionN.bind(this,item)}>
<Text style={{color: '#fff', fontSize: 18, alignSelf: 'center' }}>N</Text>
</TouchableOpacity> ||
<TouchableOpacity
style={[styles.touchable2,styles.iconStyle1]}
onPress={this.changeSelectionN.bind(this,item)}>
<Text style={{color: '#fff', fontSize: 15, alignSelf: 'center' }}>N</Text>
</TouchableOpacity>
}




</View>
</View>
}
</View>
{
this.props.navigation.state.params.props.listOfStudents !== undefined && this.props.navigation.state.params.props.listOfStudents.length >= 2 ?
<View style={styles.line} /> : <Text></Text>
}

</View>



)}
keyExtractor={item => item.id}
/>

我如何在该组件中加载数据:

componentDidMount() {



this.setState({
data: this.props.navigation.state.params.props.listOfStudents,
textOpombe: this.props.navigation.state.params.props.notes,
textVsebinaUre: this.props.navigation.state.params.props.lesson,
finished: this.props.navigation.state.params.props.finished,
absent: parseInt(this.props.navigation.state.params.props.apsent.substring(0,1)),
});
}

我如何更改平面列表中的数据;

changeCheckedToFalse = (item) => {
console.log('Item');
var arr = this.state.data;

var indexOfItem = arr.indexOf(item);
arr[indexOfItem].checked = false;
var abs = this.state.absent;
abs -= 1;
this.setState({
data: arr,
//scrollingParent: false,
//scrollingChild: true,
absent: abs,
});

console.log('State after changing: ' + JSON.stringify(this.state.data));
}

和最终代码;当更改平面列表项时,会触发此方法

componentDidUpdate(prevProps, prevState) {
console.log('Prev props: ' + JSON.stringify(prevProps));
console.log('This props: ' + JSON.stringify(this.props));

console.log('Prev state: ' + JSON.stringify(prevState));
}

最佳答案

在我看来你实际上是在改变 this.state.data/this.props.navigation.state.params.props.listOfStudents - 因为它们是一样。

我假设您包括了这一行:var arr = this.state.data; 以努力复制 this.state.data 中的值,但是恐怕它对引用类型(例如数组)不起作用。 arr 实际上指向与 this.state.data 完全相同的数组,而 this.state.data 指向与 完全相同的数组>this.props...listOfStudents

所以当你改变一个值时:arr[indexOfItem].checked = false; 你实际上是在改变 props。

React 的一个非常重要的规则是“不要改变任何东西”,那么你将如何解决这个问题?

最简单的方法是在更改之前正确复制数组:

使用展开运算符
var arr = [...this.state.data];

或者Array.prototype.slice方法
var arr = this.state.data.slice()

编辑:虽然以上是正确的,并且如果您有一个基元数组可以解决您的问题,但您实际上有一个对象引用数组,它们与上述问题完全相同。

复制数组不会复制里面的对象,只会复制对这些对象的引用,所以你有同样的问题。尝试数组的深拷贝:

var arr = this.state.data.map(x => ({...x}));

或者只复制您要更改的对象:

var arr = [...this.state.data];
var indexOfItem = arr.indexOf(item);

arr[indexOfItem] = {...item, checked: false};

关于javascript - setState 也会改变屏幕 Prop ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52401904/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com