React Native update FlatList data in pure component(纯组件中的反应本机更新FlatList数据)
本文介绍了纯组件中的反应本机更新FlatList数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我对Reaction Native有些陌生,并且一直在使用FlatList时遇到这个问题,我想更新它使用的数据源,并让它更新它自己。我的案例是有一个我想用FlatList显示的项目列表,然后每个项目都是可选择的。我看到的大多数示例都是使用组件,建议已经将state
添加到extraData
来解决这个问题。然而,我使用的是纯组件,并尝试查看在这种情况下是否有任何解决方案。遵循我创建的一个样例项目。在此示例中,发生了按下操作,data
被更新,但FlatList不反映data
更改。
import { findIndex } from 'lodash'
import React, { useState } from 'react'
import {
SafeAreaView,
StyleSheet,
View,
Text,
StatusBar,
FlatList,
Pressable,
} from 'react-native'
import {
Colors,
} from 'react-native/Libraries/NewAppScreen'
var array = require('lodash/array')
const App = () => {
const [data, setData] = useState([
{
name: "Foo",
id: '1',
isSelected: false
},
{
name: "Boo",
id: '2',
isSelected: false
},
{
name: "Koo",
id: '3',
isSelected: false
},
{
name: "Poo",
id: '4',
isSelected: false
},
{
name: "Too",
id: '5',
isSelected: false
},
{
name: "Qoo",
id: '6',
isSelected: false
},
])
const tappedItem = (item) => {
const itemIndex = data.findIndex((i) => i.id == item.id)
const newItem = data[itemIndex]
newItem.isSelected = !newItem.isSelected
data[itemIndex] = newItem
setData(data)
}
const renderItem = (item) => {
return (
<Pressable onPress={() => tappedItem(item.item)}>
<View style={[styles.sectionContainer, { backgroundColor: item.item.isSelected ? 'pink' : 'lightgray' }]}>
<Text style={styles.sectionTitle}>{item.item.name}</Text>
</View>
</Pressable>
)
}
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<View style={styles.body}>
<FlatList
data={data}
keyExtractor={item => item.id}
renderItem={renderItem}
extraData={data}
/>
</View>
</SafeAreaView>
</>
)
}
const styles = StyleSheet.create({
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
})
export default App
推荐答案
最终输出:
如何实现FlatList项的选择和取消选择:
import React, { useState } from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
StatusBar,
FlatList,
Pressable,
} from 'react-native';
const App = () => {
const [data, setData] = useState([
{
name: 'Foo',
id: '1',
isSelected: false,
},
{
name: 'Boo',
id: '2',
isSelected: false,
},
{
name: 'Koo',
id: '3',
isSelected: false,
},
{
name: 'Poo',
id: '4',
isSelected: false,
},
{
name: 'Too',
id: '5',
isSelected: false,
},
{
name: 'Qoo',
id: '6',
isSelected: false,
},
]);
const tappedItem = (item) => {
console.log(item);
const modifiedList= data.map((element) => {
if (element.id === item.id) {
return { ...element, isSelected: !element.isSelected };
}
return element;
});
setData(modifiedList);
};
const renderItem = (item) => {
return (
<Pressable onPress={() => tappedItem(item.item)}>
<View
style={[
styles.sectionContainer,
{ backgroundColor: item.item.isSelected ? 'pink' : 'lightgray' },
]}>
<Text style={styles.sectionTitle}>{item.item.name}</Text>
</View>
</Pressable>
);
};
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<View style={styles.body}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={renderItem}
extraData={data}
/>
</View>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
body: {
backgroundColor: 'white',
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: 'black',
},
});
export default App;
工作tappedItem()
:
/*
Lets assume we pressed first item in the FlatList, the item that we will be passing
is: {
name: 'Foo',
id: '1',
isSelected: false,
}
After that is done most important and also probably the easiest part,
the modification of the existing state, i.e. toggling the selected property.
*/
const tappedItem = (item) => {
console.log(item);
/*
In the following map operation, we iterate through the existing state, i.e. data.
and when we find the matching id, 1 in the case of
=> {
name: 'Foo',
id: '1',
isSelected: false,
}
we return the mutated object where we change only the `isSelected` property
You can see this happening here:
=> if (element.id === item.id) {
return { ...element, isSelected: !element.isSelected };
}
in above if statement, we spread the `element` object, toggle the `isSelected` property and return it.
If the id does not matches then we can simply return the original `element` object without any changes.
So after that, we will get the modifiedList which will have the `isSelected` toggled as we intend to.
Then we simply set the data state with that of the newly modified list.
=> setData(modifiedList);
*/
const modifiedList= data.map((element) => {
if (element.id === item.id) {
return { ...element, isSelected: !element.isSelected };
}
return element;
});
setData(modifiedList);
};
/*
this variation of your existing tappedItem function will work fine too,
just be careful not to mutate the states directly as you did in the original case
=> data[itemIndex] = newItem [❌]
=> let temp = [...data]
temp[itemIndex] = newItem; [✔]
*/
const tappedItem = (item) => {
let temp = [...data] //<= create a copy of current state
const itemIndex = data.findIndex((i) => i.id == item.id);
const newItem = data[itemIndex];
newItem.isSelected = !newItem.isSelected;
temp[itemIndex] = newItem; //<= modify that copy
setData(temp); //<= use it to set the state.
};
完整工作演示:Expo Snack
这篇关于纯组件中的反应本机更新FlatList数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:纯组件中的反应本机更新FlatList数据
基础教程推荐
猜你喜欢
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 直接将值设置为滑块 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01