javascript - 卸载屏幕后重置状态 - 挂钩?
问题描述
从 API 获取数据后,我将其设置为状态,并在 Flatlist 中呈现项目,
当我从中选择任何项目时,我会操纵数据并向名为“toggle:true”的项目对象添加一个新属性
当我从列表中选择任何项目时效果很好,我添加了一个基于的边框toggle
,但是当我返回上一个屏幕然后重新打开列表屏幕时,我可以看到项目周围呈现的边框,尽管我在卸载时重置了状态屏幕
那么我在这里做错了什么?
代码片段
数据
export default {
...
services: [
{
id: 0,
name: 'nameS0',
logo:
'https://cdn2.iconfinder.com/data/icons/hotel-98/64/hair-dryer-tools-beauty-hairdressing-512.png',
price: 19.99,
},
],
employees: [
{
id: 0,
name: 'name0',
img:
'https://www.visualelementmedia.com/wp-content/uploads/2015/04/person-4-400x629.jpg',
},
...
],
};
const VendorProfile = ({navigation}) => {
const [services, setServices] = React.useState(null);
const [employees, setEmployees] = React.useState(null);
const [serviceSelected, setServiceSelected] = React.useState(null);
const [employeeSelected, setEmployeeSelected] = React.useState(null);
// For selected Item (services, employees)
const itemSelected = (data, id) => {
const updated = data.map((item) => {
item.toggle = false;
if (item.id === id) {
item.toggle = true;
data === services
? setServiceSelected(item)
: setEmployeeSelected(item);
}
return item;
});
data === services ? setServices(updated) : setEmployees(updated);
};
...
const renderEmployees = ({item}) => {
return (
<TouchableOpacity
onPress={() => itemSelected(employees, item.id)}
delayPressIn={0}
style={styles.employeeContainer}>
<EmployeePattern style={{alignSelf: 'center'}} />
<View style={styles.employeeLogo}>
<Image
source={{uri: item.img}}
style={[styles.imgStyle, {borderRadius: 25}]}
/>
</View>
<View style={{marginTop: 30}}>
<Text style={{textAlign: 'center'}}> {item.name}</Text>
</View>
<View style={{marginTop: 10, alignSelf: 'center'}}>
{item.toggle && <AntDesign name="check" size={25} color="#000" />} // here it's stuck after back and reopen the screen
</View>
</TouchableOpacity>
);
};
React.useEffect(() => {
setServices(VendorProfileData.services);
setEmployees(VendorProfileData.employees);
() => {
setServices(null);
setEmployees(null);
};
}, []);
return (
<View style={styles.container}>
<FlatList
data={services}
renderItem={renderServices}
horizontal
keyExtractor={(item) => item.id.toString()}
contentContainerStyle={{
justifyContent: 'space-between',
flexGrow: 1,
}}
/>
.....
</View>
);
};
解决方案
好的,所以在尝试了多次后,我明白了
改变这个
const updated = data.map((item) => {
对此
const updated = data.map((old) => {
let item = {...old};
请确保一切正常,我们没有破坏任何东西:),
在您的 ItemSelected 函数上,您正在传递整个员工列表,现在通过它很好,但是当您更改此列表中的一个项目而不“重新创建它”时,对该项目的引用仍然是相同的“因为它是一个对象”意思我们正在修改原始项目,并且由于我们这样做,该项目保留其旧参考,避免这种情况的最佳方法是重新创建对象,希望这能给您一个想法。
推荐阅读
- amazon-web-services - 如何引用自动生成的角色以附加到新的 IAM 策略
- python - 不明白如何将用户点击绑定到 dataframe 中的特定对象
- asp.net - 更新后带有 Angular 的 ASP.NET Core 中的非破坏性错误
- angular - Angular - 父子组件,不能调用方法
- php - 抓取使用 php 会话的网站时遇到 cookie 错误
- python - MongoDB 地理空间数据:循环无效:边缘 8 和 10 交叉
- websocket - 网关 API - 带有安全 Websocket 的 Apache APISIX
- google-optimize - 为什么从谷歌优化运行重定向实验会在加载后显示一个空白页面然后再次显示内容?
- python - Serializer.data 提供旧值,新值在 DRF 的序列化程序中可见
- tabulator - 制表符 - 渐进式 Ajax 加载:在收到所有页面后应用过滤器